【问题标题】:Print last 10 rows of specific columns using awk使用 awk 打印最后 10 行特定列
【发布时间】:2009-07-17 14:44:42
【问题描述】:

我有下面的 awk 命令行参数,除了它在整个文件上执行打印参数(如预期的那样)之外,它还可以工作。我希望它只对文件的最后 10 行(或任意数字)执行格式化。任何建议都非常感谢,谢谢!

我知道一种解决方案是使用 tail 进行管道传输,但我想坚持使用纯 awk 解决方案。

awk '{print "<category label=\"" $13 " " $14 " " $15 "\"/>"}' foofile

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    对于 Unix shell 上的语言或工具,您无需正统。

    tail -10 foofile | awk '{print "<category label=\"" $13 " " $14 " " $15 "\"/>"}'
    

    一个很好的解决方案。而且,你已经拥有了。

    您的任意数字仍然可以用作tail的参数,不会丢失任何内容;
    解决方案不会失去任何优雅。

    【讨论】:

    • +1 对于 Unix 哲学 - 可以很好地完成任务的小型正交工具。
    【解决方案2】:

    使用环形缓冲区,这个单行打印最后 10 行;

    awk '{a[NR%10]=$0}END{for(i=NR+1;i<=NR+10;i++)print a[i%10]}'
    

    然后,您可以合并“打印最后 10 行”和“打印特定列”,如下所示;

    {
        arr_line[NR % 10] = $0;
    }
    
    END {
        for (i = NR + 1; i <= NR + 10; i++) {
            split(arr_line[i % 10], arr_field);
            print "<category label=\"" arr_field[13] " " \
                                       arr_field[14] " " \
                                       arr_field[15] "\"/>";
        }
    }
    

    【讨论】:

      【解决方案3】:

      我认为这不能在 awk 中整齐地完成。唯一的方法是缓冲最后 X 行,然后在 END 块中打印它们。

      我认为你最好坚持使用尾巴:-)

      【讨论】:

        【解决方案4】:

        仅用于最后 10 行

        awk 'BEGIN{OFS="\n"}
        {
           a=b;b=c;c=d;d=e;e=f;f=g;g=h;h=i;i=j;j=$0
        }END{    
            print a,b,c,d,e,f,g,h,i,j
        }' file
        

        【讨论】:

          【解决方案5】:

          在列数可变的情况下,我制定了两种解决方案

          #cutlast [number] [[$1] [$2] [$3]...]
          
          function cutlast {
              length=${1-1}; shift
              list=( ${@-`cat /proc/${$}/fd/0`} )
              output=${list[@]:${#list[@]}-${length-1}}
              test -z "$output" && exit 1 || echo $output && exit 0
          }
          #example:  cutlast 2 one two three print print # echo`s print print
          #example1: echo one two three four print print | cutlast 2 # echo`s print print
          

          function cutlast {
              length=${1-1}; shift
              list=( ${@-`cat /proc/${$}/fd/0`} )
              aoutput=${@-`cat /proc/${$}/fd/0`} | rev | cut -d ' ' -f-$num | rev
              test -z "$output" && exit 1 || echo $output && exit 0
          }
          
          #example:  cutlast 2 one two three print print # echo`s print print
          

          【讨论】:

            【解决方案6】:

            this text document 中有大量 awk one 衬里,不确定是否有帮助。

            这可能就是你所追求的(无论如何都是类似的):

            # print the last 2 lines of a file (emulates "tail -2")
            awk '{y=x "\n" $0; x=$0};END{print y}'
            

            【讨论】:

              【解决方案7】:
              awk '{ y=x "\n" $0; x=$0 }; END { print y }'
              

              这是非常低效的:它的作用是逐行读取整个文件,只打印最后两行。
              因为 awk 中没有 seek() 语句,所以建议使用 tail 来打印文件的最后几行。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-05-17
                • 2014-03-24
                • 1970-01-01
                • 2011-07-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多