find . -type f -name "test.php" -print0 | xargs -0 egrep -sHnl "&\s*new\s"| xargs gsed -i.bak 's/&\(\s*new\s\)/\1/gi' -
这可以很好地替换所选文件。
但我想同时看看原始文件和替换文件之间的差异。
find . -type f -name "test.php" -print0 | xargs -0 egrep -sHnl "&\s*new\s"| xargs gsed -i.bak 's/&\(\s*new\s\)/\1/gip' -
此尝试失败,但也会复制被替换的行。
find . -type f -name "test.php" -print0 | xargs -0 egrep -sHnl "&\s*new\s"| xargs gsed -n 's/&\(\s*new\s\)/\1/p' -
这可以工作,但既不覆盖原始文件(即不使用替换的文本更改它)也不备份。
有了this的灵感,我尝试遵循,但不起作用。
find . -type f -name "test.php" -print0 | xargs -0 egrep -sHnl "&\s*new\s"| xargs gsed -i.bak 's/&\(\s*new\s\)/\1/gip;s/.*\n//' -
我怎样才能实现它?
好的老板
也许 sed 的 w 选项可以提供帮助。这是一个开始;
[root@volte1 test]# cat scr.sh
sed -i '/ligne/{
s//line/g
w /dev/stdout
}' file.txt
[root@volte1 test]# cat file.txt
line1
line2
line3
line4
ligne5
line6
line7
[root@volte1 test]# ./scr.sh
line5
[root@volte1 test]# cat file.txt
line1
line2
line3
line4
line5
line6
line7
还可以尝试以下方法来输出差异之前/之后的文件:
$ cat scr2.sh
find . -name file.txt -printf '\n%p:\n' -exec sed -i '/ligne/{
h
s//line/g
H
x
s/\n/ >>> /
w /dev/fd/2
x
}' {} \;
您没有显示任何示例输入/输出,所以我不知道您真正想要做什么,但是使用 GNU awk 而不是 GNU 在将前/后行打印到 stderr 时在文件中就地进行更改将是微不足道的你正在使用的 sed:
find . -type f -name "test.php" -print0 |
xargs -0 awk -i inplace '{
print "Before:", $0 | "cat>&2"
sub(/old_regexp/,"new_string")
print "After:", $0 | "cat>&2"
} 1'
使用 awk 时不需要 grep (任何时候您使用 grep+sed 管道或多个 sed 或多个 grep,您可能应该使用单个 awk 命令),因此无论 grep 命令正在做什么都可以只需包含在 awk 脚本中,您可以使用
-exec ... +
而不是 -print0 | xargs -0
来提高效率。
使 sed 就地替换文件中的文本,并在屏幕上显示替换的行
你可以这样做:
sed 's/pattern/Rstring/g' InputFile | tee OutputFile | sed -n '/Rstring/p'
这里
pattern
是要替换的文本,Rstring
是替换字符串。
这可能对你有用(GNU sed):
seq 10 | sed '/[2468]/!b;s//&X/;w /dev/stderr > file
除 2、4、6 或 8 之外的任何行都会打印到标准输出并重定向到
file
。
任何其他行都会被替换,并打印到标准输出并重定向到
file
。
上面的行也被重定向到 stderr 并打印到终端。