如何使用 awk 计算和打印多个文件中某一列的出现次数
How to count and print the occurence of a column in multiple files using awk
我有多个制表符分隔文本文件,格式如下:
File1.txt
Sample Ind Start col1 col2 col3
ID1 1 1 f g f
ID1 1 2 f g f
ID1 1 3 f g f
ID1 1 5 f g f
File2.txt
Sample Ind Start col1 col2 col3
ID2 1 1 f g f
ID2 1 2 f g f
ID2 1 4 f g f
ID2 1 5 f g f
ID2 1 6 f g f
File3.txt
Sample Ind Start col1 col2 col3
ID3 1 1 f g f
ID3 1 3 f g f
ID3 1 7 f g f
我想计算第 2 列和第 3 列的次数,即列 '
Ind' 和 'Start' 在文件总数中找到并将计数和样本打印到新列。
输出应如下所示:
Sample Ind Start col1 col2 col3 Count Samples
ID1 1 1 f g f 3 ID1,ID2,ID3
ID1 1 2 f g f 2 ID1,ID2
ID1 1 3 f g f 2 ID1,ID3
ID1 1 5 f g f 2 ID1,ID2
ID2 1 6 f g f 1 ID2
ID3 1 7 f g f 1 ID3
这是一个包含 3 个文件的玩具示例,在实际场景中它应该与目录中的 'n' 个文件一起使用。有人可以提供一个 awk 解决方案来做到这一点。
从表面上看,这可以完成工作:
awk 'NR == 1 { OFS="\t"; print [=10=], "Count", "Samples"; next }
FNR == 1 { next }
{ if (line[,] == "")
line[,] = [=10=];
count[,]++;
if (idlist[,] != "")
idlist[,] = idlist[,] ","
else
idlist[,] =
}
END { for (idx in count) print line[idx], count[idx], idlist[idx]; }
' File*.txt
我不得不做出假设,因为这个问题没有说明或说明应该如何处理 'col1'、'col2' 和 'col3' 中的不同值(如果有的话)。我假设 'Ind' 和 'Start' 中给定值的第一行具有足够的代表性。如果需要不同的理由,则应提出新问题。
请注意,无法保证输出中值的顺序。
运行 上面关于 Mac OS X 10.10.5 和 BSD awk
问题数据的脚本产生了:
Sample Ind Start col1 col2 col3 Count Samples
ID1 1 1 f g f 3 ID1,ID2,ID3
ID1 1 2 f g f 2 ID1,ID2
ID1 1 3 f g f 2 ID1,ID3
ID2 1 4 f g f 1 ID2
ID1 1 5 f g f 2 ID1,ID2
ID2 1 6 f g f 1 ID2
ID3 1 7 f g f 1 ID3
在同一台机器上使用 GNU awk
并得到相同的数据集:
Sample Ind Start col1 col2 col3 Count Samples
ID1 1 5 f g f 2 ID1,ID2
ID2 1 6 f g f 1 ID2
ID3 1 7 f g f 1 ID3
ID1 1 1 f g f 3 ID1,ID2,ID3
ID1 1 2 f g f 2 ID1,ID2
ID1 1 3 f g f 2 ID1,ID3
ID2 1 4 f g f 1 ID2
我有多个制表符分隔文本文件,格式如下:
File1.txt
Sample Ind Start col1 col2 col3
ID1 1 1 f g f
ID1 1 2 f g f
ID1 1 3 f g f
ID1 1 5 f g f
File2.txt
Sample Ind Start col1 col2 col3
ID2 1 1 f g f
ID2 1 2 f g f
ID2 1 4 f g f
ID2 1 5 f g f
ID2 1 6 f g f
File3.txt
Sample Ind Start col1 col2 col3
ID3 1 1 f g f
ID3 1 3 f g f
ID3 1 7 f g f
我想计算第 2 列和第 3 列的次数,即列 ' Ind' 和 'Start' 在文件总数中找到并将计数和样本打印到新列。
输出应如下所示:
Sample Ind Start col1 col2 col3 Count Samples
ID1 1 1 f g f 3 ID1,ID2,ID3
ID1 1 2 f g f 2 ID1,ID2
ID1 1 3 f g f 2 ID1,ID3
ID1 1 5 f g f 2 ID1,ID2
ID2 1 6 f g f 1 ID2
ID3 1 7 f g f 1 ID3
这是一个包含 3 个文件的玩具示例,在实际场景中它应该与目录中的 'n' 个文件一起使用。有人可以提供一个 awk 解决方案来做到这一点。
从表面上看,这可以完成工作:
awk 'NR == 1 { OFS="\t"; print [=10=], "Count", "Samples"; next }
FNR == 1 { next }
{ if (line[,] == "")
line[,] = [=10=];
count[,]++;
if (idlist[,] != "")
idlist[,] = idlist[,] ","
else
idlist[,] =
}
END { for (idx in count) print line[idx], count[idx], idlist[idx]; }
' File*.txt
我不得不做出假设,因为这个问题没有说明或说明应该如何处理 'col1'、'col2' 和 'col3' 中的不同值(如果有的话)。我假设 'Ind' 和 'Start' 中给定值的第一行具有足够的代表性。如果需要不同的理由,则应提出新问题。
请注意,无法保证输出中值的顺序。
运行 上面关于 Mac OS X 10.10.5 和 BSD awk
问题数据的脚本产生了:
Sample Ind Start col1 col2 col3 Count Samples
ID1 1 1 f g f 3 ID1,ID2,ID3
ID1 1 2 f g f 2 ID1,ID2
ID1 1 3 f g f 2 ID1,ID3
ID2 1 4 f g f 1 ID2
ID1 1 5 f g f 2 ID1,ID2
ID2 1 6 f g f 1 ID2
ID3 1 7 f g f 1 ID3
在同一台机器上使用 GNU awk
并得到相同的数据集:
Sample Ind Start col1 col2 col3 Count Samples
ID1 1 5 f g f 2 ID1,ID2
ID2 1 6 f g f 1 ID2
ID3 1 7 f g f 1 ID3
ID1 1 1 f g f 3 ID1,ID2,ID3
ID1 1 2 f g f 2 ID1,ID2
ID1 1 3 f g f 2 ID1,ID3
ID2 1 4 f g f 1 ID2