使 sed 替换文件中的文本,并在屏幕上显示替换的行

Posted

技术标签:

【中文标题】使 sed 替换文件中的文本,并在屏幕上显示替换的行【英文标题】:Make sed replace text in a file in-place and also display the substituted lines on screen 【发布时间】:2018-08-21 17:08:33 【问题描述】:
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//' -

我怎样才能实现它?

【问题讨论】:

您的问题似乎与单个文件有关,那么为什么要将事情与find | xargs 混淆?将问题简化为基本要素。 如果要查看原始文件和新文件之间的差异,最简单的做法是将新数据写入新文件并调用diff。尝试进行“就地编辑”只会让您的问题变得更加困难。 威廉珀塞尔@你是对的。但是我必须替换我域中的每个文件,所以我使用这个命令,因为如果你使用'find',就不需要编写每个父路径。 William Pursell@ 是的,没错。并且使用带有 diff 插件的编辑器也是最简单的事情,尽管它们添加了额外的过程来工作。 编写一个简单的脚本来解决一个文件的问题。使用 findxargs 调用该脚本。将您的问题简化为基本要素会直接反映在您的解决方案中;将问题简化为基本组成部分并单独解决每个部分。这是使用sed -i的概念问题之一;它会阻止用户学习分解问题。 【参考方案1】:

好的老板,

也许 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
'  \;

【讨论】:

【参考方案2】:

您没有显示任何示例输入/输出,因此请了解您真正想要做什么,但是在将前/后行打印到 stderr 时在文件中进行就地更改对于 GNU awk 而不是微不足道的您正在使用的 GNU 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 或多个 seds 或多个 grep 的管道,你可能应该使用单个 awk 命令)所以无论 grep 命令是什么doing 可以只包含在 awk 脚本中,您可以只使用 -exec ... + 而不是 -print0 | xargs -0 以提高效率。

【讨论】:

【参考方案3】:

使 sed 就地替换文件中的文本,并在屏幕上显示替换的行

你可以这样做:

sed 's/pattern/Rstring/g' InputFile | tee OutputFile | sed -n '/Rstring/p'

这里pattern 是要替换的文本,Rstring 是替换字符串。

【讨论】:

以上是关于使 sed 替换文件中的文本,并在屏幕上显示替换的行的主要内容,如果未能解决你的问题,请参考以下文章

shell sed 的一些用法

2018.4.26 六周第二次课 (正则sed 替换)

sed工具

9.4/9.5 sed

正则介绍 sed

使用sed替换apache2.conf文件中的代码块内的文本