Windows CLI:将列表通过管道传输到 awk 并用外部文件中的文本替换文本并写入 output.txt
Posted
技术标签:
【中文标题】Windows CLI:将列表通过管道传输到 awk 并用外部文件中的文本替换文本并写入 output.txt【英文标题】:Windows CLI: pipe a list to awk and replace text with text from an external file and write output.txt 【发布时间】:2014-10-28 09:10:10 【问题描述】:我是这个东西的新手,遇到了这个问题,我就是想不通:
在 Windows 命令行 (cmd) 中运行的程序 (eG listfilesonhdd) 列出 hdd 上包含大量信息的文件,然后将其通过管道传输到 awk,因为某些文本(带空格)需要替换为文本(带空格) ) 在外部文本文件中,文件如下所示:
assoc.txt:
"this needs to be replaced" "with that"
"and that is replaced" "by that"
"and so on" "it goes"
"TO REPLACE" "WITH"
第一列中的文本需要替换为第二列中的文本。 awk 必须替换来自其他程序的“流”中的匹配项。
所以我尝试了这个命令行
listfilesonhdd | awk "FNR==NR assoc[$1]=$2; next; FNR<NR for(key in assoc) gsub(key, assoc[key]) printf" assoc.txt > output.txt
还有
listfilesonhdd | awk "NR==FNR a[$1]=$2; next for(i in a) for(x=1;x<=NF;x++) $x=(i==$x)?a[i]:$x1" assoc.txt > output.txt
以及我在这里找到的其他变体,但它总是给我这个错误,有时 FNR 数字会改变,不管我尝试改变什么:
awk: (FILENAME=- FNR=10) warning: error writing standard output (Invalid argument)
这可能意味着文件丢失了,它必须替换文本,但我还没有文件名,我只有这个管道数据,可以这么说。哦,用gawk也试过了,同样的错误。
我在谷歌上搜索了好几天,但我迷路了,我真的很感激,如果有人可以帮助我找到错误,请提前非常感谢你(对不起我的英语)。
【问题讨论】:
"this needs to be replaced"
不是 awk 的单个字段。它有五个字段:"this
、needs
、to
、be
和 replaced
。所以你的 awk 脚本没有做你想做的事。此外,至少在这里,awk 不会像那样从文件和标准输入中读取数据(不是没有将 -
列为文件名参数之一)。
【参考方案1】:
printf
需要参数。你可能想要print
。您可能也想删除 FNR<NR
条件,因为它没有增加任何价值。此外,Windows 引用是一场噩梦,所以请输入您的 awk 脚本:
FNR==NR assoc[$1]=$2; next
for(key in assoc) gsub(key, assoc[key]); print
在一个文件中,比如foo.awk
并执行它
listfilesonhdd | awk -f foo.awk assoc.txt - > output.txt
消除这个问题。
我使用-
表示标准输入,如果这不是 WIndows 中的语法,请适当更改(我是 UNIX 人)。
您需要告诉 awk 如何通过设置 FS 或 FPAT 或其他方式将输入分隔到字段中。
请注意,循环中的gsub(key,assoc[key])
可以替换部分匹配项(例如,您想将the
更改为a
,但发现there
转换为are
)并且可以替换已经被替换的文本,因此它是可疑的方法。您可能只想循环输入字段并执行if ($i == key) $i = assoc[key]
或类似操作。
要演示告诉 awk 如何识别字段的问题,请查看在您发布的示例输入文件上运行此操作时默认设置的空格分隔字段之间的区别:
$ awk 'NR==1for (i=1;i<=NF;i++) print NR, i, $i' assoc.txt
1 1 "this
1 2 needs
1 3 to
1 4 be
1 5 replaced"
1 6 "with
1 7 that"
vs 告诉 awk 字段是双引号之间并包含双引号的字符串:
$ awk -v FPAT='"[^"]+"' 'NR==1for (i=1;i<=NF;i++) print NR, i, $i' assoc.txt
1 1 "this needs to be replaced"
1 2 "with that"
vs 非双引号字符串:
$ awk -v FPAT='[^"]+' 'NR==1for (i=1;i<=NF;i++) print NR, i, $i' assoc.txt
1 1 this needs to be replaced
1 2
1 3 with that
最后的那些使用 FPAT,它是一个 GNU awk 扩展。其他 awk 有不同的解决方案,但这是最简单的。
【讨论】:
嗨@Ed,谢谢你的回答。当然是print而不是printf,我复制错了。我删除了 FNRlistfilesonhold
命令管道的输出示例发布到 awk 中,以及所需的输出。
我更新了我的答案以演示告诉 awk 如何识别字段的问题。以上是关于Windows CLI:将列表通过管道传输到 awk 并用外部文件中的文本替换文本并写入 output.txt的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 CLI 将 zip 文件上传和部署到 AWS elastic beanstalk?
如何将 find 命令返回的文件列表通过管道传输到 cat 以查看所有文件
我可以将多个 ffmpeg 输出通过管道传输到不同的管道吗?
支持的 libvips CLI 输出到 Windows 标准输出的格式