Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在bash上显示查找/替换多个文档的结果_Bash_Shell_Replace_Find_Xargs_Sed - Fatal编程技术网

在bash上显示查找/替换多个文档的结果

在bash上显示查找/替换多个文档的结果,bash,shell,replace,find,xargs,sed,Bash,Shell,Replace,Find,Xargs,Sed,我喜欢使用以下命令在bash中跨多个文件查找/替换: find -wholename "*.txt" -print | xargs sed -i 's/foo/bar/g' 但是,上面的命令以静默方式处理所有内容,有时我希望上面的命令打印它所做的所有更改,以便再次检查我是否正确地完成了所有操作。我可以知道应该如何改进上述命令以允许它转储此类信息吗?我在xargs命令中尝试了-v参数,但它给了我无效选项错误。您可以执行以下操作: find -wholename "*.txt"

我喜欢使用以下命令在bash中跨多个文件查找/替换:

find -wholename "*.txt" -print | xargs sed -i 's/foo/bar/g'

但是,上面的命令以静默方式处理所有内容,有时我希望上面的命令打印它所做的所有更改,以便再次检查我是否正确地完成了所有操作。我可以知道应该如何改进上述命令以允许它转储此类信息吗?我在
xargs
命令中尝试了
-v
参数,但它给了我
无效选项
错误。

您可以执行以下操作:

find -wholename "*.txt" | xargs sed -n '/foo/p;s/foo/bar/gp'
这样做的目的是打印要替换的行,并在下一行中打印替换

您可以使用
awk
并获取文件名:

find -wholename "*.txt" | xargs awk '/foo/{print FILENAME; gsub(/foo/,"bar");print}'
要打印整个文件,请删除
print
并添加
1

find -wholename "*.txt" | xargs awk '/foo/{print FILENAME; gsub(/foo/,"bar")}1'
Regex必须根据您的要求进行修改,文件中的更改仅在
gawk版本4.1中可用

测试:
$head文件*

==>file1 file2您可以执行以下操作:

find -wholename "*.txt" | xargs sed -n '/foo/p;s/foo/bar/gp'
这样做的目的是打印要替换的行,并在下一行中打印替换

您可以使用
awk
并获取文件名:

find -wholename "*.txt" | xargs awk '/foo/{print FILENAME; gsub(/foo/,"bar");print}'
要打印整个文件,请删除
print
并添加
1

find -wholename "*.txt" | xargs awk '/foo/{print FILENAME; gsub(/foo/,"bar")}1'
Regex必须根据您的要求进行修改,文件中的更改仅在
gawk版本4.1中可用

测试:
$head文件*

==>file1 file2为了查看差异,您可以将
sed
的输出重定向到每个输入文件的新文件,并将其与原始文件进行比较

for i in `find -wholename "*.txt"`; do
  sed 's/foo/bar/g' ${i} > ${i}.new;
  diff -u ${i} ${i}.new;
done
如果更改看起来正常,请将新文件移到其原始名称

for i in `find -wholename "*.new"` ; do
  mv ${i} ${i/.new};
done

为了查看差异,您可以将
sed
的输出重定向到每个输入文件的新文件,并将其与原始文件进行比较

for i in `find -wholename "*.txt"`; do
  sed 's/foo/bar/g' ${i} > ${i}.new;
  diff -u ${i} ${i}.new;
done
如果更改看起来正常,请将新文件移到其原始名称

for i in `find -wholename "*.new"` ; do
  mv ${i} ${i/.new};
done
所有这些都可以用和来完成。只需稍作修改:

find -path "*.txt" -exec sed -i.bak 's/foo/bar/g' {} +
这会调用最大数量的文件(注意
+
-exec
末尾),因此不需要。在
-i.bak
中,执行就地编辑,将原始文件重命名为
.bak
。因此,如果需要,您可以稍后检查差异

man find
中可以阅读:

-wholename pattern
      See -path.    This alternative is less portable than -path.
所有这些都可以用和来完成。只需稍作修改:

find -path "*.txt" -exec sed -i.bak 's/foo/bar/g' {} +
这会调用最大数量的文件(注意
+
-exec
末尾),因此不需要。在
-i.bak
中,执行就地编辑,将原始文件重命名为
.bak
。因此,如果需要,您可以稍后检查差异

man find
中可以阅读:

-wholename pattern
      See -path.    This alternative is less portable than -path.


你可以使用emacs:。谢谢@J.F.Sebastian提供的信息,但我是一个vim人:~你可以删除
-I
并将所有内容重定向到一个文件。如果一切正常,执行原始命令。另请参见@devnull:谢谢你的指点。我刚试过,但它似乎输出了整个文件,而不是被替换的部分@@@“,知道如何修复它吗@@@”对所有回答我问题的优秀人士说:很抱歉,我今天的票数用完了,一旦我可以再次投票,我将投票支持你的答案:~~你可以使用emacs:。谢谢@J.F.Sebastian提供信息,但我是vim的人:~你可以删除
-I
并将所有内容重定向到一个文件。如果一切正常,执行原始命令。另请参见@devnull:谢谢你的指点。我刚试过,但似乎它输出的是整个文件,而不是被替换的部分@@@“,你知道如何修复它吗@@@”对于所有回答我问题的优秀人士:很抱歉,我今天的票数不足,我将在再次投票后投票支持你的答案:~~谢谢你的回答。但是输出与我的解决方案有相同的问题,有没有办法知道哪个文件包含输出?@keelar为打印文件名添加了
awk
解决方案谢谢,我正在尝试您的解决方案,但在
/foo之后出现语法错误
print
/{
。我做错什么了吗?@keelar添加了一个示例testSure,
find-wholename“*.txt”| xargs gawk-I inplace'/foo/{print FILENAME;gsub(/foo/,“bar”);print}“
谢谢你的回答。但是输出与我的解决方案有相同的问题,有没有办法知道哪个文件包含输出?@keelar添加了打印文件名的
awk
解决方案谢谢,我正在尝试你的解决方案,但在
/foo之后出现语法错误
print
”/{
。我做错什么了吗?@keelar添加了一个示例testSure,
find-wholename“*.txt”| xargs gawk-I inplace'/foo/{print FILENAME;gsub(/foo/,“bar”);print}'