Linux 如何在bash中一次对两行进行排序,使用第二行作为索引?
我想使用bash在我的谜2梦想箱中对我的频道列表进行排序。该文件如下所示:Linux 如何在bash中一次对两行进行排序,使用第二行作为索引?,linux,bash,sorting,sed,Linux,Bash,Sorting,Sed,我想使用bash在我的谜2梦想箱中对我的频道列表进行排序。该文件如下所示: #服务4097:0:1:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM #说明新5[英文] #服务4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/11/all2.mkvM #说明全部2[英文] #服务4097:0:1:0:0:0:0:0:0:http%3A//server.com/movie/movie3.mp4M #描述
#服务4097:0:1:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM
#说明新5[英文]
#服务4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/11/all2.mkvM
#说明全部2[英文]
#服务4097:0:1:0:0:0:0:0:0:http%3A//server.com/movie/movie3.mp4M
#描述电影3[英文]
正如您在文件中看到的,每个通道由两行组成。我想在bash中每次排序两行
结果应该如下所示:
#服务4097:0:1:0:0:0:0:0:0:http%3A//server.com/movie/11/all2.mkvM
#说明全部2[英文]
#服务4097:0:1:0:0:0:0:0:0:http%3A//server.com/movie/movie3.mp4M
#描述电影3[英文]
#服务4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM
#说明新5[英文]
第一个是所有2[EN]
,上面有服务
第二个是电影movie3[EN]
,上面有服务
第三个是电影《新5[EN]
,上面有《服务》
我现在正在使用一个循环,这是非常缓慢的。我认为使用bash可以更快地完成这项工作
可能的解决方案可以是,例如:
- 将每两行合并为一行。第二行必须是第一行,并将上面的行附加到第二行。结果应该如下所示:
#描述新5[EN]#服务4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM #说明所有2[EN]#服务4097:0:1:0:0:0:0:0:0:0:0:0:0:http%3A//server.com/movie/11/all2.mkvM #描述电影3[EN]#服务4097:0:1:0:0:0:0:0:0:0:0:0:http%3A//server.com/movie/movie3.mp4M
- 分类
- 再次创建两行
sed
或tr
替换。
如何以相反的顺序连接两行?使用rev
:
rev inputfile |
awk '{printf("%s%s",$0,(NR%2==0) ? "\n" : "\r")}' |
rev | sort | tr '\r' '\n'
使用排序
键时,可以避免反转文件。我用CTRL-V CRTL-M输入了^M。我不相信你在文件名后的字母M
,也许你更喜欢#
awk解决方案:
awk '/#SERVICE/ && getline nl > 0{ print nl"|"$0 | "sort -k2,2 -k3,3" }' file
| awk -F'|' '{ print $2 ORS $1}'
输出:
#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/11/all2.mkvM
#DESCRIPTION all 2 [EN]
#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/movie3.mp4M
#DESCRIPTION movie 3 [EN]
#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM
#DESCRIPTION new 5[EN]
附加的sed方法:
sed '/#DESCRIPTION/N;{s/\n/|/}' <(tac file) | sort -k2,2 -k3,3 | sed -E 's/(.*)\|(.*)/\2\n\1/'
sed'/#说明/N;使用sed的{s/\n/|/}:
$ sed -E 'N;s/(.*)\n(.*)/\2\t\1/' infile | sort | sed -E 's/(.*)\t(.*)/\2\n\1/'
#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/11/all2.mkvM
#DESCRIPTION all 2 [EN]
#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/movie3.mp4M
#DESCRIPTION movie 3 [EN]
#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM
#DESCRIPTION new 5[EN]
第一个命令附加下一行(N
),然后交换第一行和第二行,以制表符分隔。然后通过管道将其传输到排序,第二个sed命令再次交换行,并用换行符替换选项卡
这要求在处理之前不存在制表符。awk
和sed
:
#!/usr/bin/env bash
awk '/^#SERV/ {s=$0} /^#DESC/ {print s "\t" $0}' |
sort -t $'\t' -k 2,2 |
sed 's/\t/\n/'
谢谢大家。有两种选择奏效了
选择1
awk '/^#SERV/ {s=$0} /^#DESC/ {print s "\t" $0}' file.txt | sort -t $'\t' -k 2,2 |sed 's/\t/\n/'
选择2
awk '/#SERVICE/ && getline nl > 0{ print nl"|"$0 | "sort -k2,2 -k3,3" }' /tmp/test.txt | awk -F'|' '{ print $2 ORS $1}'
现在我将学习一些高级awk命令谢谢,我使用的是第一个awk示例(选项2),效果很好。
这意味着文件(带有“成对”行(#服务和#描述))排序良好
我还有一个问题,关于一个具有相同结构的文件
是否可以扩展排序,以便:
文件是按字母顺序排序的(就像现在一样),但也使文件的顶部首先是所有高清频道(按字母顺序排序),然后是其余频道(非高清频道)。高清频道的末尾有“HD”,以“#DESCRIPTION”开头
所需输出示例:
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Action HD
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Cinema HD
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Family HD
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Action
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Cinema
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Family
命令rev不在我的Linux dreambox上。第二个选项是给出一个错误。排序:错误-t参数。如果没有rev
,您也可以尝试tac
。当tac
也丢失时,请查看。或者尝试查找另一个排序,或者尝试mansed
并找到更改分隔符的方法。或者首先使用“tr”将所有空格替换为“\r”,并在用awk连接的两行之间插入一个空格,然后再次将“\r”替换为空格。首先要澄清的问题是:根据多媒体文件名称中的建议编号,您希望对userbouquets文件进行什么排序?第二个需要澄清的问题:为什么不在我们可以根据您的需求进行调整的同时,在您的问题上添加Bash脚本?算法非常简单。这是2017年的老话题,所以我不会写bash脚本,但如果您仍然需要它,我会写。在bash脚本中,我会首先删除所有#DESCRIPTION行,因为您显然不使用它们(您只有流文件名的副本)。否则,这些行用于扩展信息。当然,您也可以处理这些#描述行(如您所愿)。然后我会在末尾的文件名中搜索将对数据进行排序的编号。因为它没有太多(只有几行),标准的数据排序算法就足够了——通过将行与所有数据内容进行比较,并将较高的数字移动到较低的数字,然后向前移动(行)。
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Action HD
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Cinema HD
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Family HD
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Action
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Cinema
#SERVICE 4097:0:1:0:0:0:0:0:0:0:...etc
#DESCRIPTION Sky Family