对包含行分隔符的文件进行排序

Sorting a file containing line delimiters

我有一个文本文件看起来像

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

选项--字段分隔符 没有任何帮助。

有没有什么方法可以通过单行、基于排序的命令来实现这一目标? 或者是提取包含行的文本、对它们进行排序并随后插入行定界符的唯一解决方案?

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

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

现在也添加了一种非线性形式的解决方案。

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

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

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

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

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

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

其实我更喜欢去掉前面的分隔符,然后排序添加,所以请重新考虑你的要求:

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