2016-01-23 118 views
1

比方說我的數據看起來像這樣替換字符

iqwertyuiop 

,我想替換所有字母我一個Z列後3 ..所以我的輸出看起來像這樣

iqwertyuZop 

我該怎麼用sed或awk做到這一點?

回答

3

目前尚不清楚你的意思是「列」,但也許這是你想要使用GNU AWK的gensub()什麼:

$ echo iqwertyuiop | awk '{print substr($0,1,3) gensub(/i/,"Z","g",substr($0,4))}' 
iqwertyuZop 
1

最直觀的方法是使用awk

awk 'BEGIN{FS="";OFS=FS}{for(i=4;i<=NF;i++){if($i=="i"){$i="Z"}}}1' file 

FS=""由字符將輸入字符串轉換成田。我們迭代低谷字符/字段4結束並用Z替換i

最後的1評估爲true並且使awk打印修改的輸入行。


隨着sed它看起來不是很intutive但它仍然是可能的:

sed -r ' 
    h      # Backup the current line in hold buffer 
    s/.{3}//    # Remove the first three characters 
    s/i/Z/g    # Replace all i by Z 
    G      # Append the contents of the hold buffer to the pattern buffer (this adds a newline between them) 
    s/(.*)\n(.{3}).*/\2\1/ # Remove that newline ^^^ and assemble the result 
' file   
+0

你能不能1)使用'y/i/Z /'(保存一個完整的字符!)2)而不是'x; s; G; s' do'G; s /(。*)\ n(...)。*/\ 2 \ 1 /'? –

+0

@BenjaminW。1)'y'命令在多行版本後需要一個';',如果它後面有註釋。不要問我爲什麼。 2)好點!補充說 – hek2mgl

1

這完全是理想的tr命令,只要你沒有要求前3字符保持不變。

但是,如果你是沒事使用一些bash的技巧加上cutpaste,你可以將文件分割成兩個部分,並將其粘貼到一起後記:

paste -d'\0' <(cut -c-3 foo) <(cut -c4- foo | tr i Z) 

上述用途paste兩個歸隊一起與cut分開的文件部分。第二部分通過tr通過管道將i轉換爲Z's。

1

(1)下面是完成一個短期和簡單的方法任務使用GNU sed的:

sed -r -e ':a;s/^(...)([^i]*)i/\1\2Z/g;ta' 

這需要循環(t),所以不會像非循環的方法一樣有效。上面也可以使用轉義括號而不是非轉義字符來編寫,因此不需要-r選項。 sed的其他實現應該(原則上)完成任務,但是您的MMV。

(2)這是很容易使用, 「舊的AWK」 以及:

awk '{s=substr($0,4);gsub(/i/,"Z",s); print substr($0,1,3) s}' 
3

Perl是得心應手這樣的:你可以分配到子

$ echo "iiiiii" | perl -pe 'substr($_,3) =~ s/i/Z/g' 
iiiZZZ