【问题标题】:how to extract columns from a text file with bash如何使用bash从文本文件中提取列
【发布时间】:2012-04-28 13:35:27
【问题描述】:

我有一个这样的文本文件。

 res          ABS   sum     
 SER A   1   161.15 138.3  
 CYS A   2    66.65  49.6  
 PRO A   3    21.48  15.8  
 ALA A   4    77.68  72.0  
 ILE A   5    15.70   9.0  
 HIS A   6    10.88   5.9 

我想根据最后一列(总和)的值提取第一列(res)的名称。如果 sum >25 和 sum

【问题讨论】:

  • 根据 cmets 中的对话,您能否澄清一下您何时真正想要打印重命名?任何数字都不能同时小于 25 和大于 25。如果sum != 25,您要打印重命名,还是要打印,例如,sum < 25 OR ABS > 25

标签: bash awk


【解决方案1】:

应该这样做:

awk 'BEGIN{FS=OFS=" "}{if($5 != 25) print $1}' bla.txt

【讨论】:

    【解决方案2】:

    虽然您可以在bash 中使用while read 循环来执行此操作,但使用awk 更容易,而且很可能更快

    awk '$5 != 25 { print $1 }'
    

    请注意,您的逻辑 print resnames if sum >25 and sum<25print if sum != 25 相同。

    【讨论】:

    • Sum > 25 and sum
    • @TimPote:所以 25 同时是 > 25 和
    • @userunknown 啊,我明白了。应用实际的布尔逻辑。抱歉,我将其解析为他 的意思 而不是他实际 所说的。是的,实际的布尔逻辑会说他不需要打印任何内容。
    • 嗯,是的,但他的意思可能是两个函数,一个选择较低的值,一个选择较高的值,但不能同时选择两者。但是 - 从您的示例代码中,制作 2 个专门的代码是微不足道的。标题是什么?
    【解决方案3】:

    考虑使用awk。它是处理文本列(以及更多)的简单工具。这是一个简单的awk tutorial,它将为您提供概述。如果您想在 bash 脚本中使用它,那么 this 教程应该会有所帮助。

    在命令行上运行它,让您了解如何做到这一点:

    > echo "SER A   1   161.15 138.3" | awk '{ if($5 > 25) print $1}'
    > SER
    > echo "SER A   1   161.15 138.3" | awk '{ if($5 > 140) print $1}'
    > 
    

    【讨论】:

      【解决方案4】:
      while read line
      do 
      v=($line)
      sum=${v[4]}
      ((${sum/.*/} >= 25)) && echo ${v[0]}
      done < file
      

      您需要跳过第一行。

      由于 bash 不处理浮点值,这将打印 25,它并不完全大于 25。

      这可以通过调用 bc 来处理算术。

      tail -n +2 ser.dat | while read line
      do  
        v=($line)
        sum=${v[4]}
        gt=$(echo "$sum > 25" | bc) && echo ${v[0]}
      done
      

      【讨论】:

        【解决方案5】:

        那么好的旧剪辑呢? :)

        说你想要第二列,

        cat your_file.txt | sed 's, +, ,g' | cut -d" " -f 2
        

        sed 在这个命令中做了什么? cut 期望列由一个字符或一个固定长度的字符串分隔(参见文档)。

        【讨论】:

        • 只是让您知道,此解决方案存在一些问题。首先,它是Useless Use of Cat 的一个典型例子。 sed 可以在不需要管道的情况下处理文件。其次,awk 没有 cut 的字段分隔符限制,因此您可以在 awk 中使用单个 print $2 执行相同操作,而无需 sed。第三,它不符合 OP 的要求。他们想有条件地打印第二个字段。你的 always 打印第二个字段。
        猜你喜欢
        • 2012-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-31
        • 2014-04-26
        • 1970-01-01
        • 2015-06-12
        • 1970-01-01
        相关资源
        最近更新 更多