Answers:
如果系统支持,则可以将sed
的w
标志与/dev/stderr
,一起使用。例如,输入如下:/dev/tty
/dev/fd/2
file
foo first
second: missing
third: foo
none here
跑步
sed -i '/foo/{
s//bar/g
w /dev/stdout
}' file
输出:
bar first
third: bar
尽管file
内容已更改为:
bar first
second: missing
third: bar
none here
因此,在您的情况下,运行:
find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
s//bar/g
w /dev/fd/2
}' {} \;
将就地编辑文件并输出:
./file1: 酒吧的东西 更多吧 ./file2: ./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
}' {} \;
就地编辑文件并输出:
./file1: foo的东西>>> bar的东西 更多foo >>> more bar ./file2: ./file3: foo首先>>> bar首先 第三名:foo >>>第三名:bar
您可以在p
第一遍中使用rint动作在两遍中完成此操作:
find . -type f | xargs sed --quiet 's/abc/def/gp'
其中--quiet
make sed不显示每一行,p
后缀仅显示替换匹配的行。
这具有的sed不会显示限制其被更改的文件,当然这可能是固定的一些额外的复杂性。
sed
表达,我不想/gp
为每一个写。如何设置全局?
我认为这是不可能的,但是一种解决方法可能是使用perl代替:
find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR'
这会将更改的行打印为标准错误。例如:
$ cat foo
fooabcbar
$ find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR'
foodefbar
您还可以使它稍微复杂一些,打印行号,文件名,原始行和更改的行:
$ find . -type f |
xargs perl -i -ne '$was=$_; chomp($was);
s/abc/def/ && print STDERR "$ARGV($.): $was : $_"'
./foo(1): fooabcbar : foodefbar
$ARGV
要操作的文件的名称。
perl
的语法与的语法非常相似sed
,但我认为您所要求的实际上并没有可能sed
。
可以使用w标志将当前模式写入文件。因此,通过将其添加到替代命令中,我们可以将连续的替代报告给文件,并在作业完成后将其打印出来。我也想用grep为替换的字符串着色。
sed -i -e "s/From/To/gw /tmp/sed.done" file_name
grep --color -e "To" /tmp/sed.done
注意,w及其文件名之间只能有一个空格。
这甚至比diff更好,因为diff也可能显示更改,即使它们不是由sed进行的。
sed.done
。因此,原始文件中带有“ To”的行不会被打印到sed.done
,因此当您grep "To" sed.done
只看到被更改的行时sed
。如果这是您要针对的,那么在替换之前,您不会在文件中看到原始行
我喜欢@terdon解决方案-perl对此非常有用。
这是我调整后的版本:
码
find /tmp/test -type f ! -name "*.bak" -exec grep -l '/opt/gridmon' {} \; | xargs -L1 perl -ni'.bak' -e'$old=$_; s/\/opt\/gridmon/~/g && print STDERR "$ARGV($.):\n\tOLD:$old\tNEW:$_"'
示例输出
/tmp/test/test4.cfg(13):
OLD: ENVFILE /opt/gridmon/server/etc/gridmonserver.cfg
NEW: ENVFILE ~/server/etc/gridmonserver.cfg
/tmp/test/test4.cfg(24):
OLD: ENVFILE /opt/gridmon/server/etc/gridmonserver.cfg
NEW: ENVFILE ~/server/etc/gridmonserver.cfg
for x in `find . -type f`; do echo ///File $x: ; sed --quiet 's/abc/def/gp' $x; done