在 awk 中获取多个压缩文件的 FILENAME

Getting FILENAME in awk for multiple compressed files

我正在尝试 运行 对多个文件执行一个命令,如果第一列等于“aaa”或等于“bbb”,该命令将打印该行 在此之前添加一列文件名。

示例文件(sample.tsv.gz):

aaa, 111, 222
bbb, 333, 444
ccc, 555, 666

我希望输出为:

sample.tsv.gz, aaa, 111, 222
sample.tsv.gz, bbb, 333, 444

我的命令是:

zcat *.tsv.gz | awk '{if (==“aaa”||==“bbb”) {print FILENAME (NF?",":"") [=12=]}}'

我得到的输出是:

-, aaa, 111, 222
-, bbb, 333, 444

我该如何解决这个问题?

您的命令正在解析由您之前命令的输出提供的 stdin,因此文件名不可用。一种处理方法是:

for f in *.tsv.gz; do
    zcat "$f" | awk -F, -v f="$f" '=="aaa" || =="bbb"{print f (NF?", ":"") [=10=]}'
done

能否请您尝试以下 find + xargs + awk 解决方案。

find *.gz -print0 | 
xargs -0 -I fname sh -c 'gzip -dc fname | awk -v file="fname" -f prog.awk'

其中 prog.awk 程序文件应包含以下内容,这负责 OP 检查第一行的第一个字段是 aaa 还是第二个字段是 bbb.

cat prog.awk
BEGIN{FS=OFS=","}
{
 if(=="aaa" || =="bbb"){
   print file,[=11=]
 }
}


以上方案测试:

  1. 让我们创建一个名为 file 的测试 Input_file,如下所示:
  2. 创建其gzip -k Input_file
  3. 通过 gzip -dc file1.gz
  4. 检查我们是否可以读取其内容
  5. 最后 运行 上面提到的命令来检查它是否工作正常。

##1st step
cat file1
aaa,bbb,ccc

##2nd step
gzip -k file1

##3rd step
gzip -dc file1.gz
aaa,bbb,ccc

##Execute solution:
find *.gz -print0 |
> xargs -0 -I fname sh -c 'gzip -dc fname | awk -v file="fname" -f prog.awk'
 Input_file.gz,aaa,bbb,ccc

另一个运行 zcat 的 awk (v.3):

awk '
BEGIN {
    FS=OFS=", "                          # delimiter in the sample data

    for(i=1;i<ARGC;i++) {                # iterating the argument files
        zcat="zcat " ARGV[i]             # zcat command
        while((zcat | getline)>0)        # process while data left
            if (=="aaa"||=="bbb") {
                print ARGV[i], [=10=]
            }
    }
}' *.gz

输出两份数据:

bar.gz, aaa, 111, 222
bar.gz, bbb, 333, 444
foo.gz, aaa, 111, 222
foo.gz, bbb, 333, 444