我编写了一个小脚本,它将递归地遍历目录中的所有 *.py 文件并替换文件中的特定条目。
所以文件及其当前内容:
find . -name "*.py" -exec ls "{}" \; -exec cat "{}" \;
返回:
./1/File1.py
import sys
./2/3/File3.py
import sys
sys.exit(1)
./6/7/File7.py
import sys
sys.exit()
./File0.py
import sys
现在我写的脚本是这样的:
for file in $(find . -name "*.py")
do
echo "$file"
sed 's/sys.exit.*/os_.exit()/g;s/import sys/&\nimport os/g' "$file"
done
现在,如果我单独运行这些 sed 命令,我将获得所需的输出。如果我在脚本中同时运行它们,或者像这样:
find . -name "*.py" -exec sed 's/sys.exit.*/os_.exit()/g' "{}" \; -exec sed 's/import sys/&\nimport os/g' "{}" \;
它最终会像这样重复我的输出:
./1/File1.py
import sys
import sys
import os
./2/3/File3.py
import sys
os_.exit()
import sys
import os
sys.exit(1)
./6/7/File7.py
import sys
os_.exit()
import sys
import os
sys.exit()
./File0.py
import sys
import sys
import os
有人可以指出我做错了什么吗?
编辑:感谢 don_crissti 发布的链接,我编辑了脚本以实际执行“one-liner”。我已将其发布在下面,感谢所有评论者的意见,它解决了我的问题。
find . -name "*.py" -exec ls "{}" \; -exec sed 's/sys.exit.*/os_.exit()/g;s/import sys/&\nimport os/g' "{}" \;
答案1
输出正如预期的那样,因为这两个sed
命令中的每一个都运行在相同的未修改的输入文本上。为了获得查询者期望的输出,两个s
替代命令应组合在一次调用中sed
:
...-exec sed -e 's/sys.exit.*/os_.exit()/g' -e 's/import sys/&\nimport os/g' "{}" \;
或者
...-exec sed 's/sys.exit.*/os_.exit()/g;s/import sys/&\nimport os/g' "{}" \;