【问题标题】:Using AWK to filter out column with numerical ranges使用 AWK 过滤掉具有数值范围的列
【发布时间】:2012-02-02 19:06:38
【问题描述】:

我对 BASH 比较陌生,我正在尝试使用 awk 根据文本文件的第 4 列过滤掉第 1 列数据。如果第 4 列数据与 x 的范围匹配,则它将输出第 1 列数据。 “x”假设是数字 1-10 (1,2,3..10) 的范围。

awk -F: '{ if($4=="x") print $1}' filename.txt

filename.txt 
sample1 0 0 4
sample2 0 0 10
sample3 0 0 15
sample4 0 0 20

实际使用:

awk -F: '{ if($4=="1-10") print $1}' sample.txt
output = sample1, sample2, sample3, sample4

应该是:仅限sample1 sample2

是否存在我没​​有看到的语法错误,或者我可能完全错误地使用了这个语法?

【问题讨论】:

    标签: bash numbers awk range


    【解决方案1】:
    awk '{ if ($4 >= 1 && $4 <= 10) print $1 }' sample.txt
    

    【讨论】:

    • 您可以将表达式用作模式并取消if,例如:awk '$4 &lt;= 10 &amp;&amp; $4 &gt;= 1 { print $1 }' file.txt
    • 另外,awk '1 &lt;= $4 &amp;&amp; $4 &lt;= 10' sample.txt 非常适合像我这样想要根据一列的值输出整行的人。
    • @arekolek 请问如果我的 1 和 10 是变量 $one 和 $ten 我该怎么办?我试过 awk '"'"$one"'"
    • @Helene,我知道one 是一个bash 变量,所以我会尝试awk "$one &lt;= \$4 &amp;&amp; \$4 &lt;= $ten",以便bash 仅替换传递给awk 的字符串中的$one$ten
    • 使用-v 选项到pass variable into awk: awk -v a="$one" -v b="$ten" 'a &lt;= $4 &amp;&amp; $4 &lt;= b'
    【解决方案2】:
    awk '$4 ~ /^[1-9]$|^10$/{print $1}' sample.txt
    

    输出:

    sample1
    sample2
    

    解释:

    • ^[1-9]$ --> $4 必须是从 1 到 9 的单个数字
    • |(管道)--> 或
    • ^10$ --> $4 必须是数字 10

    【讨论】:

      【解决方案3】:
      awk -F ':' '$4 >= 1 && $4 <= 10{print $1}'
      

      【讨论】:

      • 已在 cmets 中建议。在回答非常相似的问题之前阅读所有答案,特别是如果问题很旧。
      【解决方案4】:

      可能有一种方法可以只使用 awk(没关系,请参阅下面的编辑),但我不知道。我会把它和 grep 结合起来:

      egrep ' ([1-9]|10)$' sample.txt | awk '{print $1}'
      

      我认为您将第四列与字符串“1-10”而不是范围匹配。此外,-F: 会将分隔符更改为冒号而不是空格。

      编辑:

      awk '$4 ~ /^([1-9]|10)$/ {print $1}' sample.txt
      

      【讨论】:

        【解决方案5】:

        如果您希望awk 从某个范围内查找值,那么您可以在BEGIN 语句中设置该范围。

        awk 'BEGIN{for (i=1;i<=10;i++) a[i]} ($4 in a){print $1}' sample.txt 
        

        测试:

        [jaypal:~/Temp] cat sample.txt 
        sample1 0 0 4
        sample2 0 0 10
        sample3 0 0 15
        sample4 0 0 20
        [jaypal:~/Temp] awk 'BEGIN{for (i=1;i<=10;i++) a[i]} ($4 in a){print $1}' sample.txt 
        sample1
        sample2
        

        【讨论】:

          【解决方案6】:

          如果 Perl 是一个选项,你可以试试这个类似于 Kambus 的 awk 解决方案的解决方案:

          perl -lane 'print $F[0] if $F[3] >= 1 && $F[3] <= 10' sample.txt
          

          使用以下命令行选项:

          • -n循环输入文件的每一行,不要自动打印每一行

          • -l 在处理之前删除换行符,然后将它们添加回

          • -a 自动拆分模式 - 将输入行拆分到 @F 数组中。

          • -e执行perl代码

          @F 是每行的单词数组,从 0 开始索引

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多