在X列后替换字符

时间:2016-01-23 16:12:26

标签: awk sed

让我说我的数据看起来像这样

iqwertyuiop

我想将第3列之后的所有字母替换为Z ..所以我的输出看起来像这样

iqwertyuZop

如何用sed或awk做到这一点?

5 个答案:

答案 0 :(得分:3)

目前还不清楚“列”是什么意思,但也许这就是你想要使用GNU awk for gensub():

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

答案 1 :(得分:3)

Perl非常方便:您可以分配给子字符串

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

答案 2 :(得分:1)

最直观的方法是使用awk

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

FS=""将输入字符串按字符拆分为字段。我们通过字符/字段4迭代结束并将i替换为Z

最终1评估为true,并使awk打印修改后的输入行。

使用sed它看起来不是很直观,但仍有可能:

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         

答案 3 :(得分:1)

如果只是你没有要求前3个字符保持不变,这对tr命令来说是完全理想的。

但是,如果你可以使用一些bash技巧加上cutpaste,你可以将文件分成两部分,然后将它们粘贴在一起:

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

上面使用paste将与cut分开的文件的两个部分重新连接在一起。第二部分通过tr传送,以便将我翻译成Z&#39。

答案 4 :(得分:1)

(1)这是使用GNU sed完成任务的简单方法:

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

这需要循环(t),因此不如非循环方法有效。上面也可以使用转义括号而不是非转义字符来编写,因此不需要-r选项。 sed的其他实现(原则上)也应该完成任务,但是你的MMV。

(2)使用&#34; old awk&#34;以及:

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