如何从命令行 grep 和替换此模式?

我有很多这样的模式的 Python2 文件

datetime(2019,04,11)
datetime(2019,10,01)
datetime(2019,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() 的第二个和第三个参数。

zhengbanririye 回答:如何从命令行 grep 和替换此模式?

对于您的特定示例,Python 的 2to3 工具很有帮助。

您可以只关注 numliteral 次转化,然后再进行转化。

给定:

$ cat f.py
datetime(2019,04,11)
datetime(2019,10,01)
datetime(2019,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,11)
-datetime(2019,01)
-datetime(2019,1)
+datetime(2019,0o4,11)
+datetime(2019,0o1)
+datetime(2019,0o5,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:]]+)/\1\2/g' f.py3
datetime(2019,4,1)
datetime(2019,5,1)
,

你可以这样做:

find . -name "*.py" | xargs -d'\n' sed -i '/datetime/s/0\([0-9]\)/\1/g'
,

考虑使用 \( ... \) 表达式来匹配和保存 datetime(..., 部分:

$ cat example.py | sed  -e 's/\(datetime([^,]*,[ ]*\)0/\1/g' | sed  -e 's/\(datetime([^,[^,[ ]*\)0/\1/g'
datetime(2019,1)
,

使用 perl:

perl -pe 's{\bdatetime\s*\(.*?\)}{
  join ",",map {s/^0+(\d)/$1/r} split /,\s*/,$&,3
}ge' file

对于 datetime (...) 拆分的每个匹配项,删除前导零,然后将其重新连接在一起。

,

这可能对你有用(GNU sed):

sed -E 's/(datetime\([0-9]+,)0?([0-9]+,)0?([0-9]+)/\1\2\3/' file

对字符串 datetime 进行模式匹配,并且只捕获第二个和第三个参数中的非零前导数字。

本文链接:https://www.f2er.com/3623.html

大家都在问