bash 使用 awk 在用 find 找到的文件中查找和替换字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21174401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:17:09  来源:igfitidea点击:

Using awk to find and replace string in files found with find

regexlinuxbashcommand-lineawk

提问by Rooster

I'm using find to grab a bunch of files in a directory, and then awk to try and find/replace a string in them. However, awk is just printing the entire contents of the files to stdout instead of overwriting the files. I'm a bit confused as to what syntax I should use here to accomplish my goal.

我正在使用 find 抓取目录中的一堆文件,然后使用 awk 尝试查找/替换其中的字符串。但是,awk 只是将文件的全部内容打印到标准输出而不是覆盖文件。我有点困惑我应该在这里使用什么语法来实现我的目标。

My command so far is:

到目前为止,我的命令是:

find -iname '*_input.xml' -exec awk -P '/"prop_name" : "ID",/ , /}/ {print sub(/SKU/,"SKU+ProductId")} 1' {} +

THis is replacing the string SKUwith SKU+ProductIdbut not overwriting the file.

这是替换字符串SKUSKU+ProductId而不是覆盖该文件。

Any one have any ideas as to what Im missing?

任何人对我缺少什么有任何想法?

Cheers!

干杯!

Update:Example Content:

更新:示例内容:

          },
      "prop_name" : "ID",
      "rule" : "SKU"
   },

回答by kojiro

awk writes to standard output, so you will need to redirect standard output. You can do that with findby executing an inner shell command:

awk 写入标准输出,因此您需要重定向标准输出。你可以find通过执行一个内壳命令来做到这一点:

find -iname '*_input.xml' \
     -exec sh -c 'for file; do
       ./awk_script "$file" > "$file.tmp" && mv "$file.tmp" "$file"
      done' _ {} +

I would move the awk command to its own file to avoid problems with quoting. You may also want to consider saving the task of overwriting the original files until you've checked the results.

我会将 awk 命令移动到它自己的文件中以避免引用问题。在检查结果之前,您可能还需要考虑保存覆盖原始文件的任务。

You could create an awk file like this, I believe. Don't forget to chmod +xit.

我相信你可以像这样创建一个 awk 文件。不要忘记chmod +x它。

#!/usr/bin/awk -f

/"prop_name" : "ID",/ , /}/ {
    print sub(/SKU/,"SKU+ProductId")
} 1

回答by that other guy

GNU sed has a -ifor in place editing that makes this a lot easier:

GNU sed 有一个-i就地编辑功能,让这件事变得更容易:

find -iname '*_input.xml' \
  -exec sed -i '/"prop_name" : "ID",/ , /}/ s/SKU/SKU+ProductId/' {} +

回答by Ed Morton

You need to use a new-ish version of GNU awk (4.?) with the -i infileoption and get rid of the print.

您需要使用带有该-i infile选项的新版本的 GNU awk (4.?)并去掉print.