【问题标题】:Sorting a file containing line delimiters对包含行分隔符的文件进行排序
【发布时间】:2018-06-26 12:47:24
【问题描述】:

我有一个看起来像这样的文本文件

text_a_3   xxx   yyy
- - - - - - - - - - -
text_b_2   xyx   zyz
- - - - - - - - - - - 
text_b_3   xxy   zyy
- - - - - - - - - - -
text_a_2   foo   bar
- - - - - - - - - - -
text_a_1   foo   bla
- - - - - - - - - - -
text_b_1   bla   bla 

我想根据第一个字段对该文件进行数字排序,以便我的输出如下所示:

text_a_1   foo   bla
- - - - - - - - - - -
text_a_2   foo   bar
- - - - - - - - - - -
text_a_3   xxx   yyy
- - - - - - - - - - -
text_b_1   bla   bla 
- - - - - - - - - - -
text_b_2   xyx   zyz
- - - - - - - - - - - 
text_b_3   xxy   zyy

我认为 sort 会完成这项工作。因此我尝试了

sort -n name_of_my_file
sort -k1 -n name_of_my_file

但它给了

- - - - - - - - - - - 
- - - - - - - - - - - 
- - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - -
text_a_1   foo   bla
text_a_2   foo   bar
text_a_3   xxx   yyy
text_b_1   bla   bla 
text_b_2   xyx   zyz
text_b_3   xxy   zyy

--field-separator 选项没有任何帮助。

有没有什么方法可以通过单行、基于排序的命令来实现这一点? 或者是提取包含行的文本,对其进行排序,然后插入行分隔符的唯一解决方案?

【问题讨论】:

    标签: bash sorting field delimiter


    【解决方案1】:

    仅使用 GNU awk,并依赖内部排序函数 asort() 并将记录分隔符设置为虚线:

    awk -v RS='- - - - - - - - - - -\n' '
      {a[++c]=$0}
      END{
        asort(a)
        for(i=1;i<=c;i++) 
          printf "%s%s",a[i],(i==c?"":RS)
      }' name_of_my_file
    

    脚本首先将输入文件的内容填充到数组a中。读取文件时,对数组进行排序,然后使用相同的输入记录分隔符打印。

    【讨论】:

    • 我喜欢这个,虽然我看不懂(i==c?"":RS)的意思
    • @EdouardIFP 这是标准的if ... then ... else ... 声明的简明方式。 IE。仅当不是最后一条记录时才打印记录分隔符。
    【解决方案2】:

    当行分隔符都在偶数行时,可以使用

    paste -d'\r' - - < yourfile | sort -n | tr '\r' '\n'
    

    我实际上更喜欢删除前面的分隔符,然后排序并添加它们,所以请重新考虑您的要求:

    grep -Ev "(- )*-" yourfile | sort -n | sed 's/$/\n- - - - - - - - - - -/'
    

    【讨论】:

      【解决方案3】:

      关注sort + awk 可能会对您有所帮助。

      sort -t"_" -k2 -k3 Input_file | awk '/^-/ && !val{val=$0} !/^-/{if(prev){print prev ORS val};prev=$0} END{print prev}'
      

      现在也添加非单线形式的解决方案。

      sort -t"_" -k2 -k3  Input_file |
      awk '
      /^-/ && !val{
        val=$0}
      !/^-/{
        if(prev){
          print prev ORS val};
        prev=$0
      }
      END{
        print prev
      }'
      

      【讨论】:

      • 感谢您的回答。我不明白为什么要设置“_”作为字段分隔符?
      • @EdouardIFP,如果我们不这样做,那么默认情况下,空格将作为分隔符,然后结果会有所不同。
      猜你喜欢
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多