我想使用bash在我的enigma2 dreambox中对我的频道列表进行排序。该文件如下所示:
#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM
#DESCRIPTION new 5[EN]
#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]
正如您在文件中看到的,每个通道包含两行。我想在bash中每次排序两行。
结果应如下所示:
#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]
第一个是all 2 [EN]
,其上方有SERVICE
。
其次是电影movie 3 [EN]
,其上方有SERVICE
。
第三部分是电影new 5[EN]
,其上方有SERVICE
。
我现在正在使用循环,这非常慢。我认为这可以使用bash
更快地完成可能的解决方案可能是,例如:
将每两行合并为一行。第二行必须是第一行并将上面的行附加到它。结果应如下所示:
#DESCRIPTION new 5[EN]#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/1/new.aviM
#DESCRIPTION all 2 [EN]#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/11/all2.mkvM
#DESCRIPTION movie 3 [EN]#SERVICE 4097:0:1:0:0:0:0:0:0:0:http%3A//server.com/movie/movie3.mp4M
排序
答案 0 :(得分:1)
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 :(得分:0)
在接下来的解决方案中,我将在连接的行之间使用\ r \ n。在一个简单的Unix文本文件中,你不会有那些愚蠢的Window事物,它可以被sed
或tr
替换。
如何以相反的顺序连接两条线?使用rev
:
rev inputfile |
awk '{printf("%s%s",$0,(NR%2==0) ? "\n" : "\r")}' |
rev | sort | tr '\r' '\n'
使用sort
密钥时,可以避免反转文件。我用CTRL-V CRTL-M输入^ M.在文件名后我不相信你的来信M
,也许你更喜欢#
awk '{printf("%s%s",$0,(NR%2==0) ? "\n" : "\r")}' file |
sort -t'^M' -k2,1 | tr '\r' '\n'
答案 2 :(得分:0)
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/'
答案 3 :(得分:0)
使用sed:
$ 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
),然后交换第一行和第二行,制表符分隔。然后将其传送到sort
,第二个sed命令再次交换行,并用换行符替换选项卡。
这要求在处理之前不存在制表符。
答案 4 :(得分:0)
谢谢大家。有两种选择。
选项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命令
答案 5 :(得分:0)
谢谢,我正在使用第一个AWK示例(选项2),并且运行良好。 这意味着文件(带有“成对”的行(#SERVICE和#DESCRIPTION))排序良好。
关于具有相同结构的文件,我还有另一个问题。
是否可以扩大排序范围,这样:
该文件按字母顺序排序(与现在一样),但也要确保该文件的顶部是所有高清通道(按字母顺序排序),然后是其余所有高清通道(非高清通道)。 HD频道的行尾确实有“ 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