gpt4 book ai didi

linux - 如何在表的每一列上循环 awk 命令并输出到单个输出文件?

转载 作者:太空狗 更新时间:2023-10-29 11:38:36 27 4
gpt4 key购买 nike

我有一个由单个单元 1、2 和 3 组成的多列文件。每列中有很多重复的单元,有时会从一个单元切换到另一个单元。我想计算此切换在每一列上发生了多少次。例如,在第 1 列中,开关从 1 变为 2 变为 3 变为 1,因此有 3 个开关,输出应为 3。在第二列中,整个列有 2s,因此变化为 0,输出为 0 .

我的输入文件有 4000 列,所以不可能手工完成。该文件以空格分隔。

例如:

输入:

1 2 3 1 2 
1 2 2 1 3
1 2 3 1 2
2 2 2 1 2
2 2 2 1 2 ......
3 2 2 1 2
3 2 2 1 1
1 2 2 1 1
1 2 2 1 2
1 2 2 1 1

期望的输出:

3    ## column 1 switch times
0 ## column 2 switch times
3 .....
0
5

我正在使用:

awk '{print $1}' <inputfile> | uniq | wc -l
awk '{print $2}' <inputfile> | uniq | wc -l
awk '{print $3}' <inputfile> | uniq | wc -l
....

这一次执行一列。它会给我第一列的输出“4”,稍后我将计算 4-1 =3 以获得我想要的输出。但是有没有一种方法可以将这个 awk 命令写入循环并在每一列上执行它并输出到一个文件?

谢谢!

最佳答案

awk 告诉您变量 NF 的给定行中有多少个字段,因此您可以创建两个数组来跟踪您需要的信息。一个数组将保留给定列中最后一行的值。另一个将计算给定列中的开关数。您还将跟踪最大列数(并将新列的计数设置为零,以便如果该列的开关数为 0,它们将在最后的输出中正确打印)。您还将确保不计算从空字符串到非空字符串的转换 — 这发生在第一次遇到该列时。

如果实际上文件的列数一致,那只会影响第一行数据。如果后续行实际上比第一行有更多的列,那么它会添加它们。如果一列停止出现了一点,我假设它应该从它停止的地方恢复(就好像丢失的列与以前的值相同)。您可以决定不同的算法;这可以算作两次转换(从数字到空白以及从空白到数字。如果是这种情况,您必须修改计数代码。或者,也许更明智地,您可以决定根本不允许不规则数量的列,在这种情况下,如果当前行中的列数与上一行中的列数不同,您可以提前退出(注意空行,否则它们也被禁止了吗?)。

而且您不会尝试将整个程序写在一行中,因为这会让人难以理解,而且确实没有必要。

awk '{   if (NF > maxNF)
{
for (i = maxNF + 1; i <= NF; i++)
count[i] = 0;
maxNF = NF;
}
for (i = 1; i <= NF; i++)
{
if (col[i] != "" && $i != col[i])
count[i]++;
col[i] = $i;
}
}
END {
for (i = 1; i <= maxNF; i++)
print count[i];
}' data-file-with-4000-columns

鉴于您的示例数据(删除了点),脚本的输出符合要求:

3
0
3
0
5

这个带有锯齿状行的替代数据文件:

1 2 3 1 2
1 2 2 1 3
1 2 3 1 2
2 2 2 1 2
2 2 2 1 2 1 1 1
3 2 2 1 2 2 1
3 2 2 1 1
1 2 2 1 1 2 2 1
1 2 2 1
1 2 2 1 1 3

产生输出:

3
0
3
0
3
2
1
0

根据我制定的规则,这是正确的——但如果您决定要用不同的规则来覆盖数据,您最终可能会得到不同的答案。

如果您在最后一个循环中使用了 printf("%d\n", count[i]);,则无需在循环中将计数值设置为零。您付钱并选择。

关于linux - 如何在表的每一列上循环 awk 命令并输出到单个输出文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14718035/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com