2013-11-27 68 views
5

我有幾百行格式化爲這樣一個文件:行排序按字母順序使用AWK和/或sed的

#blah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/xyz(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#xblah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/hkf(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#ablah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/abc/.*(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

我想創造AWK腳本/ sed的使用按字母順序排列文件每組文本的第三行中的第二個參數。在這個文件的情況下,它是「abc」,「hkf」或「xyz」,它可以是任何東西 - 它們是在這個apache重定向文件中創建的重定向。

我計算過,我想要做的是:

  1. 串連使用排序-k3,3
  2. 每組三線​​成一條線與
  3. 各行之間的分隔符排序線然後重新組裝3線與分離空白行
  4. 寫構建到文件

我預計產量將看起來像這樣:

#ablah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/abc/.*(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#xblah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/hkf(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#blah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/xyz(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

這是否有意義?有一個更好的方法嗎?

p.s.我的意圖是使腳本可移植,以便可以在此結構的多個文件上使用它。在提出解決問題的代碼時,請儘可能詳細說明問題,以便像我這樣的排名新手開始瞭解如何有效地解決此問題,並能夠擴展最終結果。

任何和所有幫助非常感謝。

+2

什麼是從上面輸入預期的輸出文件? – anubhava

+0

anubhava,我編輯了我的OP,我認爲它現在更有意義。 – user3043123

+0

sed不適合排序,所以awk將成爲您的工具 – NeronLeVelu

回答

1

你的想法似乎是一個再簡單不過的方法。這似乎適用於我的測試數據。它確實增加了額外的空白行,我現在還沒有足夠的重點來解決這個問題。

awk '/^#/,/^$/ {printf "%s\0",$0} /^$/ {print ""} END {print ""}' 20250937.input | sort -t'\0' -k3,3 | tr '\0' '\n' 
  1. 對於/ ^#/和/^$ /打印的線條勾勒出了空,而不是一個新行終結之間的所有行。
  2. 當我們看到一個空行還打印出一個換行符。
  3. 確保我們的產量是由一個換行符終止。
  4. 排序對我們的田地。
  5. 變換空回換行。
+0

我已經能夠編輯awk命令來處理2行而不是3行,但是我想知道如何修改上面的命令以便能夠在同一個文件中處理2行和3行? – user3043123

+0

awk不知道任何有關注釋和塊結束之間的行數。關心伯爵的唯一部分就是這種。您需要能夠定義要在什麼地方排序的內容,以及排序目標是否會移動(或更糟糕的是,在塊之間不一致),這會使事情變得複雜。 –

1

一些SED版本:

sed -n '/^#/{N;h;n;H;x;s/\n/XnlX/g;x;s!.*\^/\([a-z]*\).*!\1!;G;s/\n/ /;p}' input \ 
     | sort | sed 's/[^ ]* //;s/$/\n/;s/XnlX/\n/g' 

產地:

#ablah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/abc/.*(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#xblah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/hkf(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#blah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/xyz(|/)$ http://www.blah.com/404.html [R=301,L,NC] 
5

你可以做了GNU AWK整個操作:

awk -f sort.awk input.txt 

其中sort.awk

BEGIN { 
    RS="" 
} 
{ 
    match($0,/RewriteRule \^\/(.*)\(\|/,a) 
    key[NR]=a[1] "\t" NR 
    block[NR]=$0 
} 

END { 
    asort(key) 
    for (i=1; i<=NR; i++) { 
     split(key[i],a,"\t") 
     print block[a[2]] 
     printf "\n" 
    } 
} 

產地:

#ablah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/abc/.*(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#xblah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/hkf(|/)$ http://www.blah.com/404.html [R=301,L,NC] 

#blah 
RewriteCond %{HTTP_HOST} www.blah.com [NC] 
RewriteRule ^/xyz(|/)$ http://www.blah.com/404.html [R=301,L,NC] 
+2

這個awk腳本是非常好的證明,試圖用幾種方法打破它 - 似乎目前還沒有。非常感謝您的解決方案。爲了理解這個新的邏輯,我需要一段時間反對我的頭腦。非常感謝。 – user3043123