我还没有踏入,awk
但这是我明年学习的任务。我问了之前的一个问题,这让我想到了awk
并且它有效。但是,我不确定如何输入所有文件类型并输出awk
.例子:
- 查找所有
.xml
文件 - 位于
file.xml
- 执行
awk
脚本 - 保存为
file.xml
我awk
在 bash 中研究发现这但我认为它不会解决当前 awk 代码打印回文件的问题.xml
。对于我来说,当前运行脚本是我必须做的gawk -f file.sh < file.xml
。
我的目标是搜索所有.xml
文件,运行代码,并将新.xml
文件保存在同一位置。
编辑:经过几次搜索后,我能够将其输出回 xml:
gawk -f awk.sh < file.xml > file.xml
答案1
如果您不介意使用其他工具,find
则还应该研究该命令,特别是 -exec 选项,或将其与该xargs
命令结合起来。 (也调查一下find ... -print0 | xargs -0 ...
)
答案2
您有几个问题需要解决。
至少您必须为 AWK 脚本提供一个文件列表,因为它没有内置的方法来搜索目录。这可以通过 shell 或通过find
.也有几种不同的方法可以将该列表传递给 AWK。
如果您的脚本首先成功处理其内容并将输出保存到临时文件,您还必须小心,仅覆盖原始文件。
您还必须认真考虑要对这些 XML 文件执行什么操作。 XML(以及所有类似的类似 SGML 的“语言”)的语法极其难以解析。
如果您首先从最后一个问题开始,并设法创建一个简单的脚本,该脚本将有效地成为一个过滤程序,它将处理标准输入上提供给它的一个输入文件,将结果写入标准输出,那么您已经解决了最重要的一步,正如您所猜测的,您可以通过命令行上的文件重定向简单地测试它,但是您必须非常小心,不要覆盖或截断您的输入文件:
awk -f script.awk < input_file > output_file
一些简单的 shell 语法将帮助您通过将输出文件重命名为与脚本成功时相同的名称来转换输入文件(从而解决第二个问题):
awk -f script.awk < input_file > output_file && mv output_file input_file
仅当前面的命令&&
运行并以成功状态退出(退出代码为0
.
现在您终于可以解决处理大量文件的第一个问题了。在文件列表上迭代上述命令的最简单方法是使用一个简单的小 shell 循环,一次读取一个文件名并使用上面的命令处理它:
while read fn; do
awk -f script.awk < "${fn}" > "${fn}.out" && mv "${fn}.out" "${fn}" || break
done
如果进程失败,这|| break
将导致循环终止,为失败的文件awk
留下部分文件。.out
另请注意变量扩展的仔细引用——这可以确保正确处理包含空格的文件名。
现在,该while read
循环当然只会等待您输入一个文件名,然后输入另一个文件名,依此类推,直到您中断它或向它发送一个 EOF 字符。因此,很简单,您可以使用 向其提供文件名列表find
,如下所示:
find . -name '*.xml' -print | while read fn; do
....
您可以将这一切包装在一个小脚本中,或者只是在命令行上键入它。
如果您确实制作了一个小 shell 脚本,那么可以交替地让循环while
遍历命令行参数列表,并将每个参数视为要处理的文件名。这样,您就可以使用 shell 文件名扩展来生成要处理的文件列表,就像许多处理命令行上给出的文件列表的 UNIX 程序一样。然后你可以使用for
这样的循环:
for fn
do
....
(请注意,第一行变量名称后面没有分号!)
您还可以修改 AWK 脚本以从标准输入读取文件名列表,并使用system()
调用mv
.