在运行之前测试递归sed搜索并替换


13

sed在实际运行之前,有什么方法可以运行试验性递归搜索并使用来替换?我只想在实际进行搜索和替换之前打印出结果。像是回荡结果,

grep -rl term1 . |xargs sed -i -e 's/term1/term2/'

复制数据,运行命令,检查结果。
库萨兰达

Answers:


10

您可以sed不运行而-i使用less

grep -rl --null term1 . | xargs -0 sed -e 's/term1/term2/' | less

然后运行sed-i.bak创建备份,你可以事后diff的

grep -rl --null term1 . | xargs -0 sed -i.bak -e 's/term1/term2/'
diff somefile.bak somefile
# verify changes were correct

编辑:如注释中所建议,使用grep --null | xargs -0。这将导致文件名以空字节终止,这使得使用诸如换行符之类的不寻常字符的文件名安全。是的,\n是Unix文件名中的有效字符。唯一禁止使用的字符是斜杠/和nul字符\0


有趣的是,我尝试查找-i的含义,但未在man sed中列出。您的解决方案有效。您认为仅列出行而不是整个文件的最佳方法是什么?而不是用更少的管道来管道 grep term2,可以用,但我也得到一些带有奇怪字符的输出。
user251482 2014年

@ user251482-“仅列出行”,例如“查看旧文件与新文件之间的差异”?
grebneke 2014年

1
@StephaneChazelas是的,甚至更好,grep -rl --null因为OP没有指定OS,这-Z意味着在BSD / OSX上有所不同(解压缩)。--null在GNU和BSD上都相同
grebneke 2014年

1
@grebneke。很好,但是请注意,OP使用的是GNU sed语法,因此我们可以假定他不在BSD上。请注意,这grep是FreeBSD和NetBSD上的GNU grep(的一个分支)。在NetBSD上,-Z仍然意味着--null(根据手册页),但是我同意--null更可移植。还要注意的是,无论--null也不在OpenBSD -Z工作
斯特凡Chazelas

1
@grebneke,它是sed -i '' -e s/.../在BSD sed(没有可选选项有)
斯特凡Chazelas

5

使用sedfind替代grep

首先,我将雇用find而不是grep,这是出于三个充分的理由:

  1. find允许更精确的文件选择。例如,grep -r string *.txt仅在当前目录中产生文件;而不是子目录中的那些。
  2. find带有功能强大的-exec选项,从而消除了对整个--null … |xargs 0结构的需求。
  3. -readable-writable选项find将防止浪费时间在无法访问的文件上。

捕获测试

就是说,grep确实适合进行第一个测试以查看将捕获的内容:

$ find . -exec grep term1 {} \;

或更具体地说:

$ find . -type f -name '*.txt' -readable -writable -exec grep term1 {} \;

空运行

现在,进行sed空转。该sed选项-n为同义词--quietp在的最后sed表达将打印当前模式空间。

$ find . -exec sed -n 's/term1/term2/gp' {} \;

或更具体地说:

$ find . -type f -name '*.txt' -readable -writable -exec sed -n 's/term1/term2/gp' {} \;

执行

如果一切正常,通过更换发出明确的命令sed选项,-n通过-i对“到位”,并通过去除p底。

$ find . -exec sed -i 's/term1/term2/g' {} \;

或更具体地说:

$ find . -type f -name '*.txt' -readable -writable -exec sed -i 's/term1/term2/g' {} \;

更多find例子

find这里可以找到更多示例。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.