让我说我的数据看起来像这样
iqwertyuiop
我想将第3列之后的所有字母替换为Z ..所以我的输出看起来像这样
iqwertyuZop
如何用sed或awk做到这一点?
答案 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技巧加上cut
和paste
,你可以将文件分成两部分,然后将它们粘贴在一起:
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}'