对包含行定界符的文件进行排序

时间:2018-06-26 12:47:25

标签: bash sorting field delimiter

我有一个类似的文本文件

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 没有任何帮助。

有没有一种方法可以通过单行,基于排序的命令来实现? 还是提取包含行的文本,对其进行排序并在其后插入行定界符的唯一解决方案?

3 个答案:

答案 0 :(得分: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中。读取文件后,将对数组进行排序,然后使用相同的输入记录分隔符进行打印。

答案 1 :(得分:1)

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

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

我实际上更喜欢删除前面的定界符,然后对其进行排序和添加,因此请重新考虑您的要求:

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

答案 2 :(得分:0)

遵循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
}'