如果所有值都相同,则循环遍历 bash 测试中的列 - AWK

Posted

技术标签:

【中文标题】如果所有值都相同,则循环遍历 bash 测试中的列 - AWK【英文标题】:Loop over columns in bash testing if all values are the same - AWK 【发布时间】:2021-11-24 22:27:58 【问题描述】:

我想遍历文件中的每一列并检查所有值是否匹配。如果他们这样做,请转到下一列。一旦检测到不匹配,循环将停止并仅打印到前一列。我认为我需要在 AWK 中使用数组,但不知道如何开始。这是我正在使用的数据集的示例:

superkingdom:Eukaryota phylum:Arthropoda class:Insecta order:Diptera family:Culicidae genus:Anopheles species;annularis
superkingdom:Eukaryota phylum:Arthropoda class:Insecta order:Diptera family:Culicidae genus:Anopheles species;dirus
superkingdom:Eukaryota phylum:Arthropoda class:Insecta order:Diptera family:Culicidae genus:Anopheles species;dirus
superkingdom:Eukaryota phylum:Arthropoda class:Branchiopoda order:Anostraca family:Thamnocephalidae genus:Branchinella species;pinnata
superkingdom:Eukaryota phylum:Arthropoda class:Insecta order:Diptera family:Culicidae genus:Culex species;hayashii
superkingdom:Eukaryota phylum:Arthropoda class:Branchiopoda order:Diplostraca family:Daphniidae genus:Daphnia species;ambigua
superkingdom:Eukaryota phylum:Arthropoda class:Branchiopoda order:Diplostraca family:Daphniidae genus:Daphnia species;ambigua
superkingdom:Eukaryota phylum:Arthropoda class:Branchiopoda order:Diplostraca family:Daphniidae genus:Daphnia species;carinata

循环遍历列(由“”分隔),前两列在所有行中匹配,但随后第三列(类)不匹配,因此循环将停止并仅打印前两个字段,例如

superkingdom:Eukaryota phylum:Arthropoda
superkingdom:Eukaryota phylum:Arthropoda
superkingdom:Eukaryota phylum:Arthropoda
superkingdom:Eukaryota phylum:Arthropoda
superkingdom:Eukaryota phylum:Arthropoda
superkingdom:Eukaryota phylum:Arthropoda
superkingdom:Eukaryota phylum:Arthropoda
superkingdom:Eukaryota phylum:Arthropoda

基本上,我喜欢保留/打印具有相同值的列,而不是保留/打印具有多个值的列。

脚本将从第 1 列/字段开始并测试所有值是否相同(比较字符串):如果是(如示例数据中的情况),则继续到第 2 列。测试是否所有值都是在第 2 列中相同(它们是),所以转到第 3 列。测试第 3 列中的所有值是否相同(它们不是)。所以,停止循环/中断,只打印具有相同值的先前列。

不确定从什么代码开始。

这个想法是遍历文件中的字段并打印列直到存在不匹配的地方,通过测试#唯一值是否大于 1 来确定

for ... do cut -f"$i" -d " " | sort -u>tmpf; if [ $(wc -l < tmpf) = "1" ]; then awk 'printf "%s ;", $0' tmpf; else break; fi; done

唱片

【问题讨论】:

添加您希望我们帮助您的代码。 你可以用任何你喜欢的语言来做。 awk 是一个选项,但不是必需的。但是我不确定我是否正确理解了您的问题:例如,如果文件最后一行中的第一个字段与最后一行不同,是否意味着您只想打印空行?或许您可以在不专注于特定实现的情况下,勾勒出您心目中的算法。 很遗憾,您等到问题关闭后才添加缺少的代码,现在我们都只需要等待,看看您是否有足够的票数重新打开它,然后才能有人回答。 @RavinderSingh13 OP 已经提出了一个关于它的新问题。 @EdMorton,感谢先生告知,因为上次 cmets 是关于重新开始投票,所以我已经投票了,如果它在一个新问题中得到照顾,那么可能应该由 OP 删除,但它进来了OP 的盘子,干杯。 【参考方案1】:

当您想要使用列时,请先转置文件,然后再使用行。来自An efficient way to transpose a file in Bash:

transpose() 
    awk '
     
        for (i=1; i<=NF; i++)  
            a[NR,i] = $i
        
    
    NF>p  p = NF 
    END     
        for(j=1; j<=p; j++) 
            str=a[1,j]
            for(i=2; i<=NR; i++)
                str=str" "a[i,j];
            
            print str
        
    '

然后:

transpose < input | awk '
   # Check if all fields are equal
    for (i=1;i<NF;++i) if ($i != $(i+1)) stop=1; 
   # If not equal print previous lines
   stop for (i in lines) print(lines[i]); exit 
   # Remember the line if not stopped.
    lines[linescnt++] = $0 
' | transpose

【讨论】:

以上是关于如果所有值都相同,则循环遍历 bash 测试中的列 - AWK的主要内容,如果未能解决你的问题,请参考以下文章

在linux shell(bash)编程中,如何通过递归方式遍历文件

动态循环遍历Python函数中的函数列表

python尝试不同的随机数进行数据划分使用卡方检验依次计算不同随机数划分下训练接和测试集所有分类特征的卡方检验的p值,如果所有p值都大于0.05则训练集和测试集都具有统计显著性数据划分合理

循环遍历数据框中的列以按类别生成直方图

循环遍历列以获取基于标题的列号

使用 if 语句遍历列表