【问题标题】:How can I change file content with find and awk?如何使用 find 和 awk 更改文件内容?
【发布时间】:2012-07-01 06:53:08
【问题描述】:

我遇到以下问题 - 我想遍历某个目录下的所有 xml 文件,并为我找到的所有 id-s 加上某个前缀。为此,我编写了以下脚本:

#!/bin/bash
find . -iregex .+?\.xml -print -exec awk '{print gensub(/(.*?)=\"(@(\+|)id)\/(.+)\"/, "\\1=\"\\2/prefix_\\4\"", "g", $1);}' {} > {} \;

但是重定向部分 - > {} 不起作用。该脚本将运行良好并按预期在标准输出上打印所有内容,但似乎无法将输出重定向到 awk 读取的同一文件。知道如何规避这个问题吗?谢谢!

【问题讨论】:

  • 澄清一下,您希望在同时写入文件的同时读取文件
  • 没有。我期待awk print ... {} 输出一些将被重定向到 awk 读取的文件的内容。不过这似乎是不可能的。

标签: regex shell replace awk find


【解决方案1】:

改为执行 bash:

find . -iregex .+\.xml -print \
-exec bash -c "awk '{print gensub(/(.*?)=\\"(@(\+|)id)\/(.+)\\"/, \"\\1=\"\\2/prefix_\\4\\"\", \"g\", \$1);}' {} > {}.NEW" \;

这将完全覆盖您正在读取的文件(这就是我将.NEW 添加到我要重定向到的文件的原因)。也许您想要的是 >>(附加)重定向器?


由于您没有在问题中提供示例文件,因此很难提出一个完整的工作示例。但是,以下工作:

如果您有一个名为 tmp.xml 的文件,其中包含以下内容:

I have a "
I do not

然后运行:

find . -name '111.xml' -exec bash -c "awk '\$0 ~ /\"/ { print \$0 }' {} > {}.NEW" \;

文件tmp.xml.NEW 将包含:

I have a "

请注意,除了双引号之外,您还必须在脚本中转义您的美元 ($),因为 shell 将它们视为变量。

【讨论】:

  • 即使在正确转义后也不起作用。我通过使用第三个文件重定向到输出然后从中复制来解决它,但我对此并不满意。有没有更好的办法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2014-02-11
  • 2017-06-30
  • 1970-01-01
  • 2018-04-04
  • 1970-01-01
  • 2020-12-03
相关资源
最近更新 更多