2017-03-16 188 views
-4

我有一個文件的條目類似如下:的Unix Shell腳本:AWK/SED循環

root:x:0::192.168.164.164 
bin:x:1:bin,daemon:192.168.164.164 
daemon:x:2:bin,daemon:192.168.164.164 
test:x:501:test1,test2,test3,test4:192.168.164.160 
test5:x:502::192.168.164.160 

我一直在尋找UNIX的bash/shell腳本的方式通過該文件可以轉化爲:

root;0;;192.168.164.164 
bin;1;bin;192.168.164.164 
bin;1;daemon;192.168.164.164 
daemon;2;bin;192.168.164.164 
daemon;2;daemon;192.168.164.164 
test;501;test1;192.168.164.160 
test;501;test2;192.168.164.160 
test;501;test3;192.168.164.160 
test;501;test4;192.168.164.160 
test5;502;;192.168.164.160 
+0

似乎是一個微不足道的'awk'命令。使用':'作爲輸入字段分隔符,';'作爲輸出字段分隔符,然後打印您想要的字段。 – Barmar

+1

啊,這比它稍微複雜一些。當字段4包含逗號時,您需要將其拆分,然後爲該數組的每個元素重複打印。 – Barmar

+0

所以這行'test:x:501:test1,test2,test3,test4:192.168.164.160'應該轉換成'test; 501; test1; 192.168.164.160 test; 501; test2; 192.168.164.160 test; 501; test3; 192.168.164.160 test; 501; test4; 192.168.164.160',對吧? – RomanPerekhrest

回答

1

在bash:

while IFS=: read -r a b c d e; do 
    while IFS=, read -r -a i; do 
    [[ ${#i[@]} -eq 0 ]] && i="" 
    for j in "${i[@]}"; do 
     echo "$a;$c;$j;$e" 
    done 
    done <<< "$d" 
done < file 

輸出:

 
root;0;;192.168.164.164 
bin;1;bin;192.168.164.164 
bin;1;daemon;192.168.164.164 
daemon;2;bin;192.168.164.164 
daemon;2;daemon;192.168.164.164 
test;501;test1;192.168.164.160 
test;501;test2;192.168.164.160 
test;501;test3;192.168.164.160 
test;501;test4;192.168.164.160 
test5;502;;192.168.164.160 
1

鑑於你新更新的要求:

awk -F'[:,]' -v OFS=';' '{for(i=4;i<NF;i++) print $1, $3, $i, $NF}' file 
+0

這很好,謝謝!但我正在玩另一個實際測試案例,其中文件包含另一個條目,如: testuser4:x:502 :: 192.168.164.160 然後代碼去掉(如預期的)502到192.168.164.160之間的所有內容。但是,它應該顯示類似於 testuser4; 502 ;; 192.168.164.160 –

+1

道歉 - 我對測試用例和問題文本感到無情。我現在糾正了他們。 –

+1

感謝您的反饋和答案,Ed!在下次發佈之前,請牢記您的建議。這就像一個魅力:) –

0

的Perl:

perl -F'[:,]' -lanE '$,=";"; print @F[0,2],$_,$F[-1] for @F[3..$#F-1]' file