2017-08-22 68 views
1

我想使用bash在enigma2 dreambox中對我的頻道列表進行排序。該文件是這樣的:如何在bash中一次排序兩行,使用第二行作爲索引?

#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

在接下來的解決方案中,我將使用\ r加入的行之間。在一個普通的Unix文本文件中,你不會有那些愚蠢的Window事物,它可以用sedtr來代替。 如何按相反順序連接兩行?使用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' 
+0

命令** **轉速是不是在我的Linux的Dreambox。第二個選項是給出錯誤。 排序:bad -t parameter。 – simo

+0

如果沒有'rev',你也可以嘗試'tac'。如果缺少'tac',請查看https://stackoverflow.com/q/22328828/3220113。或者嘗試找到另一種類型或嘗試'man sed'並找到改變分隔符的方法。或者,首先用'tr'替換所有空格,然後在兩個要加入awk的行之間插入一個空格,再用空格替換'\ r'。 –

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/' 
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命令再次交換行並用換行符替換該選項卡。

這要求在處理之前沒有製表符。

1

awksed

#!/usr/bin/env bash 

awk '/^#SERV/ {s=$0} /^#DESC/ {print s "\t" $0}' | 
    sort -t $'\t' -k 2,2 | 
    sed 's/\t/\n/' 
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命令

相關問題