从xargs接收字符串变量时出现awk问题



ls subset/*.txt | cut -d "/" -f 2 | cut -d "." -f 1 | xargs -i awk '$2 == {} {print $3,$4 > $2}' data.txt

有人能帮我为什么这不起作用吗?

我在子集目录中有一个文件列表,我想取这些文件名。ls subset/*.txt | cut -d "/" -f 2 | cut -d "." -f 1这部分表明我已经成功地分离了文件名。

然后,我想在data.txt中查找与文件名匹配的带有$2的行,并在文件名$2下保存字段$3和$4。

我一直在尝试不同的版本,但没有一个能满足我的要求。关于xargs-I选项,我想有一些我不知道的地方,但我就是搞不明白。有人能帮忙吗?

我的文件在子集目录中是

file1.text

file2.txt

file3.txt

我的data.txt包含数千个文件的数据,其中只有一个子集在subset目录中。data.txt中的每一行都是一个记录文件:例如这样。

xxxx文件2 34 45 xxxx xxxx xxxx xxxx

xxxx文件1 54 30 xxxx-xxxx-xxx-xxx

vvvd文件2 23 30 xfxx flkd sdlfkj dfs

我只想分别保存字段3和字段4,这样输出看起来像这样。

file2.txt的内容:

34 45

23 30

file1.text:的内容

54 30

您的xargs命令不起作用,因为它正在用正在使用的文本替换awk命令中的{},因此在该上下文中,文本似乎是从未设置过的awk变量名,因此当您希望它们是字符串时,它们为空。要将该文本视为字符串,您需要将{}放在双引号内。外观:

$ printf 'foon' | xargs -i awk 'BEGIN{ print {} }'
$ printf 'foon' | xargs -i awk 'BEGIN{ print "{}" }'
foo

第一个命令相当于试图打印名为foo:的未填充变量的值

awk 'BEGIN{ print foo }'

第二个是您想要的,打印文本字符串"foo":

awk 'BEGIN{ print "foo" }

如果没有样本输入/输出,这只是一个猜测,但看起来这可能是你想要做的:

awk '
BEGIN {
for (; ARGC>2; ARGC--) {
fname = ARGV[ARGC-1]
delete ARGV[ARGC-1]
sub(".*/","",fname)
sub(".[^.]+$","",fname)
fnames[fname]
}    
}
$2 in fnames { print $3, $4 >> $2; close($2) }
' data.txt subset/*.txt

这只是对awk的1次调用,不需要lsxargs等,除非subset下有太多文件,超过了shell的最大arg长度。

最新更新