2013-11-27 14 views
5

Tôi có một tập tin với vài trăm dòng định dạng như vậy:dòng Sorting trong một tập tin theo thứ tự abc sử dụng awk và/hoặc 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] 

Tôi muốn tạo ra một kịch bản trong awk/sed để alphabetize tập tin này bằng đối số thứ hai trong dòng thứ ba của mỗi nhóm văn bản. Trong trường hợp của tệp này, đó là "abc", "hkf" hoặc "xyz" có thể là bất kỳ điều gì - chúng là các chuyển hướng được tạo trong tệp chuyển hướng apache này.

I figured rằng những gì tôi muốn làm là:

  1. concatenate từng nhóm ba dòng vào một dòng với một dấu phân cách giữa mỗi dòng
  2. loại các dòng sử dụng loại -k3,3
  3. sau đó tái lắp ráp các dòng 3 xây dựng với một dòng trống tách
  4. ghi vào tập tin

sản lượng dự kiến ​​của tôi sẽ trông giống như sau:

#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] 

Điều này có hợp lý không? Có cách nào tốt hơn để làm điều này?

p.s. ý định của tôi là làm cho tập lệnh di động để nó có thể được sử dụng trên một số tệp của cấu trúc này. Khi đề xuất mã để giải quyết vấn đề, hãy đánh vần nó ra tốt nhất có thể cho một thứ hạng newb như tôi để bắt đầu hiểu cách giải quyết vấn đề này một cách hiệu quả và có thể mở rộng kết quả cuối cùng.

Bất kỳ và tất cả trợ giúp được đánh giá cao.

+2

gì được mong đợi tập tin đầu ra từ trên đầu vào? – anubhava

+0

anubhava, tôi đã chỉnh sửa OP của mình, tôi nghĩ giờ đây có ý nghĩa hơn. – user3043123

+0

sed không phù hợp để phân loại nên awk sẽ là công cụ của bạn – NeronLeVelu

Trả lời

1

Ý tưởng của bạn dường như là một phương pháp đủ đơn giản. Điều này dường như làm việc cho tôi về dữ liệu thử nghiệm của bạn. Nó có thêm các dòng trống thừa và tôi không tập trung đủ vào lúc này để sắp xếp.

awk '/^#/,/^$/ {printf "%s\0",$0} /^$/ {print ""} END {print ""}' 20250937.input | sort -t'\0' -k3,3 | tr '\0' '\n' 
  1. Đối với tất cả ranh giới giữa/^ #/và/^ $/in các dòng ra với một null thay vì một terminator xuống dòng.
  2. Khi chúng tôi thấy một dòng trống cũng in ra một dòng mới.
  3. Đảm bảo đầu ra của chúng tôi bị chấm dứt bằng một dòng mới.
  4. Sắp xếp trên các trường của chúng tôi.
  5. Biến đổi null trở lại thành dòng mới.
+0

Tôi đã có thể chỉnh sửa lệnh awk để xử lý 2 dòng thay vì 3, nhưng tôi đã tự hỏi làm thế nào tôi có thể sửa đổi lệnh trên để có thể xử lý cả 2 và 3 dòng trong cùng một tệp? – user3043123

+0

Đó là awk không biết bất cứ điều gì về số lượng các dòng giữa bình luận và kết thúc của khối. Phần duy nhất quan tâm đến tính là loại. Bạn cần có khả năng xác định những gì sắp xếp ở đâu đó và nếu mục tiêu sắp xếp của bạn di chuyển (hoặc tệ hơn, không nhất quán giữa các khối) sẽ làm cho mọi thứ trở nên phức tạp. –

1

Một số phiên bản 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' 

Tạo:

#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

Bạn có thể làm toàn bộ hoạt động trong Gnu AWK:

awk -f sort.awk input.txt 

nơi 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" 
    } 
} 

Tạo:

#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

Kịch bản awk này là khá bằng chứng đạn, cố gắng để phá vỡ nó một vài cách - dường như không thể cho đến nay. Cảm ơn bạn rất nhiều vì giải pháp. Tôi cần phải đánh đầu chống lại nó một lúc để hiểu được logic - mới ở đây. Cảm ơn bạn rất nhiều. – user3043123

Các vấn đề liên quan