如何报告“sed”就地更改

ric*_*cab 28 sed text-processing replace

当使用sed就地替换字符串时,有没有办法让它报告它所做的更改(不依赖于新旧文件的差异)?

例如,如何更改命令行

find . -type f | xargs sed -i 's/abc/def/g'
Run Code Online (Sandbox Code Playgroud)

这样我就可以看到即时所做的更改?

msw*_*msw 21

您可以使用p第一遍的rint 操作分两次通过:

find . -type f | xargs sed --quiet 's/abc/def/gp'
Run Code Online (Sandbox Code Playgroud)

where--quiet使 sed 不显示每一行,p后缀只显示替换匹配的行。

这有一个限制,即 sed 不会显示哪些文件正在更改,当然可以通过一些额外的复杂性来修复。


don*_*sti 21

你可以使用sed的w标志有两种/dev/stderr,/dev/tty,/dev/fd/2如果您的系统支持。例如,输入file如下:

foo first
second: missing
third: foo
none here
Run Code Online (Sandbox Code Playgroud)

跑步

sed -i '/foo/{
s//bar/g
w /dev/stdout
}' file
Run Code Online (Sandbox Code Playgroud)

输出:

bar first
third: bar
Run Code Online (Sandbox Code Playgroud)

虽然file内容改为:

bar first
second: missing
third: bar
none here
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下,运行:

find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
s//bar/g
w /dev/fd/2
}' {} \;
Run Code Online (Sandbox Code Playgroud)

将就地编辑文件并输出:

./文件1:
酒吧的东西
更多酒吧

./文件2:

./file3:
酒吧第一
第三:酒吧

您还可以打印类似的内容,original line >>> modified line例如:

find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
h
s//bar/g
H
x
s/\n/ >>> /
w /dev/fd/2
x
}' {} \;
Run Code Online (Sandbox Code Playgroud)

就地编辑文件并输出:

./文件1:
foo 的东西 >>> 酒吧的东西
更多 foo >>> 更多酒吧

./文件2:

./file3:
foo 优先 >>> bar 优先
第三:foo >>> 第三:bar


ter*_*don 8

我认为这是不可能的,但一种解决方法可能是使用 perl:

find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR' 
Run Code Online (Sandbox Code Playgroud)

这会将更改后的行打印为标准错误。例如:

$ cat foo
fooabcbar
$ find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR' 
foodefbar
Run Code Online (Sandbox Code Playgroud)

您还可以稍微复杂一点,打印行号、文件名、原始行和更改的行:

$ find . -type f | 
   xargs perl -i -ne '$was=$_; chomp($was);
                      s/abc/def/ && print STDERR "$ARGV($.): $was : $_"' 
./foo(1): fooabcbar : foodefbar
Run Code Online (Sandbox Code Playgroud)


小智 5

可以使用w标志将当前模式写入文件。因此,通过将其添加到替换命令中,我们可以将连续替换报告到文件并在作业完成后打印它。我还喜欢用 grep 对替换的字符串进行着色。

sed -i -e "s/From/To/gw /tmp/sed.done" file_name
grep --color -e "To" /tmp/sed.done
Run Code Online (Sandbox Code Playgroud)

请注意, w与其文件名之间只能有一个空格。

这甚至比 diff 更好,因为 diff 也可能显示更改,即使它们不是由 sed 生成的。