如何执行仅创建已更改文件备份的 sed 就地替换?

Bel*_*dez 14 linux scripting sed shell-script

我运行以下命令来替换当前工作目录中所有文件中使用的术语:

$ find . -type f -print0 | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'
Run Code Online (Sandbox Code Playgroud)

这执行了单词替换,但它也创建.bup了从未有Ms. Johnson字符串的文件的文件。

如何在不创建所有这些不必要的备份的情况下执行替换?

Jan*_*der 9

Find 有一个-exec执行任意命令的操作符。更好的-exectest,因此您可以将多个-execs 链接在一起,如果前面的命令失败,则后面的命令将不会被执行。该字符串{}被替换为当前文件名,并;标记命令的结束。您应该引用两者以避免 shell 干扰。

所以:

find . -type f \
    -exec grep -q 'Ms. Johnson' '{}' \; \
    -exec sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g' '{}' \;
Run Code Online (Sandbox Code Playgroud)


amp*_*ine 8

您可以检查文件的内容以确保sed在对它们进行操作时会发生替换:

find . \
    -type f \
    -exec grep -q 'Ms. Johnson' {} \; \
    -print0 |
xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'
Run Code Online (Sandbox Code Playgroud)

如果你想真正聪明一点,你可以完全放弃使用find

grep -Z -l -r 'Ms. Johnson' |
    xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'
Run Code Online (Sandbox Code Playgroud)


Kev*_*vin 5

我查看了手册页,没有看到任何直接通过 执行此操作的方法sed,正如我确信您在询问之前所做的那样。我看到有几种使用 grep 解决这个问题的方法,但我认为最简单的是:

grep -rlZ "Ms. Johnson" . | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'
Run Code Online (Sandbox Code Playgroud)

-r递归
-l打印文件名仅以
-Z空结尾的名称