对包含行分隔符的文件进行排序
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- - - - - - - - - - -/'
我有一个文本文件看起来像
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- - - - - - - - - - -/'