将 for 循环元素的数量传递给外部命令

Pass number of for loop elements to external command

我正在使用 for 循环遍历目录中的 .txt 文件并从文件中获取指定的行。之后输出被传递给 pr 命令,以便将其打印为 table。一切正常,但我手动指定 table 应包含的列数。当文件数量不固定时,这很麻烦。

我正在使用的命令:

for f in *txt; do awk -F"\t" 'FNR ~ /^(2|6|9)$/{print }' $f; done | pr -ts --column 4

我应该如何修改命令以将“4”替换为元素编号?

编辑: 基本问题是是否可以提供匹配的文件编号以在循环外运行。看到解决方案,我想不可能解决这个问题。在此结论之前,文件的结构并不真正相关。 但是,考虑到上述因素,我提供了以下文件结构。

样本file.txt:

Irrelevant1 text
Placebo 1222327
Irrelevant1 text
Irrelevant2 text
Irrelevant3 text
Treatment1  105956
Irrelevant1 text
Irrelevant2 text
Treatment2  49271
Irrelevant1 text
Irrelevant2 text

for 循环从 4 个 *txt 文件生成以下内容:

1222327
105956
49271
969136
169119
9672
1297357
237210
11581
1189529
232095
13891

预期 pr 使用动态生成的输出 --column 4:

1222327 969136  1297357 1189529
105956  169119  237210  232095
49271   9672    11581   13891

您可以 运行 ls 并将输出通过管道传输到 wc -l。然后一旦你得到那个数字,你就可以将它分配给一个变量并将该变量放在你的命令中。

num=$(ls *.txt | wc -l)

我忘记了如何在 AWK 中放置 bash 变量,但我认为您可以做到。如果没有,请回复,我会尝试找到不同的答案。

假设:

  • 所有输入文件生成相同数量的输出行(否则我们可以添加一些代码来跟踪最大行数并根据需要生成空白列)

设置(列为 tab-delimited):

$ grep -n xxx f[1-4].txt
f1.txt:6:xxx    1222327
f1.txt:9:xxx    105956
f1.txt:24:xxx   49271
f2.txt:6:xxx    969136
f2.txt:9:xxx    169119
f2.txt:24:xxx   9672
f3.txt:6:xxx    1297357
f3.txt:9:xxx    237210
f3.txt:24:xxx   11581
f4.txt:6:xxx    1189529
f4.txt:9:xxx    232095
f4.txt:24:xxx   13891

使用 awk 动态构建 'table' 的一个想法(替换 OP 当前的 for 循环):

awk -F'\t' '
FNR==1             { c=0 }
FNR ~ /^(6|9|24)$/ { ++c ; arr[c]=arr[c] (FNR==NR ? "" : " ")  }
END                { for (i=1;i<=c;i++) print arr[i] }
' f[1-4].txt | column -t -o ' '

注意: 我们将继续让 column 用一个 space 来处理 pretty-printing table ] 分隔列,否则我们可以使用 spaces

添加更多代码到 awk 到 right-pad 列

这会生成:

1222327 969136 1297357 1189529
105956  169119 237210  232095
49271   9672   11581   13891