2017-08-30 27 views
1

這是我的文件。替換|字符之間的記錄與管道分隔文件中的值

NAME|NUM|ADDR|AGE 
abcd|02|abc|cd|12 
jake|04|xy|zzb|12 
lau|92||xcx| 56 

我需要的輸出必須是這樣

NAME|NUM|ADDR|AGE 
abcd|02|abc#cd|12 
jake|04|xy#zzb|18 
    lau|92|#xcx| 56 

我的檔案有4場和第3欄在人物之間的管道分隔符,如「冰|膏」,我的要求是,替換| (#,*或任何其他值)的第三個字段。由於這是管道分隔的文件我無法替換的文件exclusively.Any幫助,特別是部分將是me..thanks

回答

3

AWK解決方案非常有用:

awk -F'|' 'NR==1;NR>1 && NF>4{ print $1,$2,$3"#"$4,$5 }' OFS='|' file 
  • NR==1; - 打印第一紀錄是

  • NR>1 && NF>4 - 檢查是否記錄有過多場

  • $3"#"$4 - 破滅的第三和第四場用新的字符替換分隔#

輸出:

NAME|NUM|ADDR|AGE 
abcd|02|abc#cd|12 
jake|04|xy#zzb|12 
lau|92|#xcx| 56 
+0

謝謝你的幫助。羅馬,我使用korn shell(ksh)是我得到這個錯誤的原因「-ksh:awk -F | NR == 1; NR> 1 && NF> 4 {s = $ 3」#「$ 4 ;打印$ 1,$ 2,s,$ 5} OFS = |:找不到[沒有這樣的文件或目錄]「,而我用你提供的soln u。 –

+0

你可以在沒有額外變量的情況下完成它:'print $ 1,$ 2,$ 3「#」$ 4,$ 5' – valrog

+0

@valrog,那是爲了演示的目的 – RomanPerekhrest

1

或者,如果你想要一個更傳統的基於邏輯的解決方案,(和 - )這裏是另一種解決方案

awk -F\| 'BEGIN{OFS="|"} 
    { 
    #dbg print "#dbg:NF="NF; 

    # if this record has an extra character 
    if (NF>4){ 
     # loop over all fields 
     for(i=1;i<=NF;i++){ 
     # if not the field of interest or last field on line, just print it 
     if(i!=3 && i!=NF){ 
      printf("%s|",$i) 
     } 
     # else this is the problem field, add the # char 
     else if (i==3){ 
      printf $3"#" 
     } 
     # else if last field on line, add LF char at end 
     else if (i==NF){ 
      printf ("%s\n",$i) 
     } 
     } 
    } 
    # record has correct number of FS chars 
    else { 
     print $0 
    } 
    }' dat.txt 

輸出

NAME|NUM|ADDR|AGE 
abcd|02|abc#cd|12 
jake|04|xy#zzb|12 
lau|92|#xcx| 56 

我添加註釋的代碼解釋是怎麼回事。


這是爲所有重要的一行; - >

awk -F\| '{if (NF>4){for(i=1;i<=NF;i++){if(i!=3 && i!=NF){printf("%s|",$i)}else if(i==3){printf $3"#"}else if(i==NF){printf ("%s\n",$i)}}}else{print $0}}' dat.txt 

IHTH

1

只需設置n到要與現場相結合取其場的數量之後:

$ cat tst.awk 
BEGIN { FS=OFS="|" } 
NR==1 { print; next } 
{ 
    for (i=1;i<=NF;i++) { 
     sep = (i==n ? "#" : OFS) 
     printf "%s%s", $i, (i<NF ? sep : ORS) 
    } 
} 

$ awk -v n=3 -f tst.awk file 
NAME|NUM|ADDR|AGE 
abcd|02|abc#cd|12 
jake|04|xy#zzb|12 
lau|92|#xcx| 56 

$ awk -v n=2 -f tst.awk file 
NAME|NUM|ADDR|AGE 
abcd|02#abc|cd|12 
jake|04#xy|zzb|12 
lau|92#|xcx| 56 
+0

實際上,我不希望第二和第三列之間的管道(「|')被移除,如果你看看第三列,例如:Ed | 11 | TX | HOUSE | 45,我需要這個Ed | 11 | TX#HOUSE | 45假設如果我的rec如:Ed | 11 || TXHOUSE | 45,那麼它必須更改爲Ed | 11 | #TXHOUSE | 45 –

+0

再看看我的答案。通過設置變量'n',每個腳本從不同位置移除管道的腳本之後,通過兩個單獨的示例向您展示如何從任意位置移除管道。因此,如果您想更改第10個'''在每一行上設置一個'#',你就可以設置'n = 10'。第一個例子(使用'n = 3')正好產生你說你希望從你輸入的輸入中得到的輸出。真的是一個問題。 –

相關問題