如何从命令行 grep 和替换此模式?
How to grep and replace this pattern from command line?
我有很多 Python2 个具有这样模式的文件
datetime(2019, 04, 11)
datetime(2019, 10, 01)
datetime(2019, 04, 05, 1, 1)
要将此代码迁移到 Python3,我必须删除第二个和第三个日期时间参数中的前导 0。
我知道如何将 sed 用于像这样的简单模式:
sed -e 's/01/1/g' -e 's/02/2/g' -e 's/03/3/g' my.py
但我的模式更复杂:我应该只修改 datetime() 的第二个和第三个参数。如何使用 sed 或任何其他命令行工具执行此操作?
以下命令尝试使用像这样的简单静态模式在代码库中查找要修改的所有字符串:
find . -name "*.py" | xargs grep datetime | grep '01\|02\|03\|04\|05\|06\|07'
但它也存在与上述相同的问题:grep 模式不够具体 - 上述模式不应查看整个字符串,只能查看 datetime() 的第二个和第三个参数。
考虑使用 \( ... \)
表达式来匹配和保存 datetime(...,
部分:
$ cat example.py | sed -e 's/\(datetime([^,]*,[ ]*\)0//g' | sed -e 's/\(datetime([^,]*,[^,]*,[ ]*\)0//g'
datetime(2019, 4, 11)
datetime(2019, 10, 1)
datetime(2019, 4, 5, 1, 1)
这可能适合您 (GNU sed):
sed -E 's/(datetime\([0-9]+, )0?([0-9]+, )0?([0-9]+)//' file
在字符串datetime
上进行模式匹配,只捕获第二个和第三个参数中的非零前导数字。
对于您的特定示例,Python 的 2to3 工具很有帮助。
您可以只关注 numliteral
转化,然后再进行转化。
鉴于:
$ cat f.py
datetime(2019, 04, 11)
datetime(2019, 10, 01)
datetime(2019, 04, 05, 1, 1)
你可以这样做:
$ 2to3 -n -w --add-suffix=3 -f numliterals f.py
RefactoringTool: Refactored f.py
--- f.py (original)
+++ f.py (refactored)
@@ -1,3 +1,3 @@
-datetime(2019, 04, 11)
-datetime(2019, 10, 01)
-datetime(2019, 04, 05, 1, 1)
+datetime(2019, 0o4, 11)
+datetime(2019, 10, 0o1)
+datetime(2019, 0o4, 0o5, 1, 1)
RefactoringTool: Writing converted f.py to f.py3.
RefactoringTool: Files that were modified:
RefactoringTool: f.py
将 04
替换为 0o4
现在您对正则表达式有了一个更具体的目标:
$ sed -E 's/([[:space:]]*)0o([[:digit:]]+)//g' f.py3
datetime(2019, 4, 11)
datetime(2019, 10, 1)
datetime(2019, 4, 5, 1, 1)
你可以这样做:
find . -name "*.py" | xargs -d'\n' sed -i '/datetime/s/0\([0-9]\)//g'
我有很多 Python2 个具有这样模式的文件
datetime(2019, 04, 11)
datetime(2019, 10, 01)
datetime(2019, 04, 05, 1, 1)
要将此代码迁移到 Python3,我必须删除第二个和第三个日期时间参数中的前导 0。
我知道如何将 sed 用于像这样的简单模式:
sed -e 's/01/1/g' -e 's/02/2/g' -e 's/03/3/g' my.py
但我的模式更复杂:我应该只修改 datetime() 的第二个和第三个参数。如何使用 sed 或任何其他命令行工具执行此操作?
以下命令尝试使用像这样的简单静态模式在代码库中查找要修改的所有字符串:
find . -name "*.py" | xargs grep datetime | grep '01\|02\|03\|04\|05\|06\|07'
但它也存在与上述相同的问题:grep 模式不够具体 - 上述模式不应查看整个字符串,只能查看 datetime() 的第二个和第三个参数。
考虑使用 \( ... \)
表达式来匹配和保存 datetime(...,
部分:
$ cat example.py | sed -e 's/\(datetime([^,]*,[ ]*\)0//g' | sed -e 's/\(datetime([^,]*,[^,]*,[ ]*\)0//g'
datetime(2019, 4, 11)
datetime(2019, 10, 1)
datetime(2019, 4, 5, 1, 1)
这可能适合您 (GNU sed):
sed -E 's/(datetime\([0-9]+, )0?([0-9]+, )0?([0-9]+)//' file
在字符串datetime
上进行模式匹配,只捕获第二个和第三个参数中的非零前导数字。
对于您的特定示例,Python 的 2to3 工具很有帮助。
您可以只关注 numliteral
转化,然后再进行转化。
鉴于:
$ cat f.py
datetime(2019, 04, 11)
datetime(2019, 10, 01)
datetime(2019, 04, 05, 1, 1)
你可以这样做:
$ 2to3 -n -w --add-suffix=3 -f numliterals f.py
RefactoringTool: Refactored f.py
--- f.py (original)
+++ f.py (refactored)
@@ -1,3 +1,3 @@
-datetime(2019, 04, 11)
-datetime(2019, 10, 01)
-datetime(2019, 04, 05, 1, 1)
+datetime(2019, 0o4, 11)
+datetime(2019, 10, 0o1)
+datetime(2019, 0o4, 0o5, 1, 1)
RefactoringTool: Writing converted f.py to f.py3.
RefactoringTool: Files that were modified:
RefactoringTool: f.py
将 04
替换为 0o4
现在您对正则表达式有了一个更具体的目标:
$ sed -E 's/([[:space:]]*)0o([[:digit:]]+)//g' f.py3
datetime(2019, 4, 11)
datetime(2019, 10, 1)
datetime(2019, 4, 5, 1, 1)
你可以这样做:
find . -name "*.py" | xargs -d'\n' sed -i '/datetime/s/0\([0-9]\)//g'