我有一个包含行的文件:
india;austria;japan;chile
china;US;nigeria;mexico;russia
我想用 eg 替换每行上出现的所有分号;NEW;
,但仅从第二次出现开始。结果应该是这样的:
india;austria;NEW;japan;NEW;chile
china;US;NEW;nigeria;NEW;mexico;NEW;russia
我用 gsub 尝试过此操作,但它替换了所有发生的情况:
awk '/;/{gsub(/;/,";NEW;") }{print}'
答案1
该awk
解决方案更长,但更容易使其通用:
awk -F\; '{for(i=1;i<NF;i++)printf"%s;%s",$i,(i>=2)?"NEW;":"";print$NF}' replacefile
也可以这样做sed
,使用命令进行循环t
并始终将第二个(或您想要的任何一个)分隔符替换为一些临时标记(通常\n
):
sed ':b;s/;/\n/2;tb;s/\n/;NEW;/g' replacefile
答案2
GNU sed 命令有一个标志s///
可以执行此操作:
sed 's/;/;NEW;/2g' <<END
india;austria;japan;chile
china;US;nigeria;mexico;russia
END
输出
india;austria;NEW;japan;NEW;chile
china;US;NEW;nigeria;NEW;mexico;NEW;russia
看https://www.gnu.org/software/sed/manual/sed.html#The-_0022s_0022-命令
该
s
命令后面可以跟零个或多个以下标志:
g
将替换应用于正则表达式的所有匹配项,而不仅仅是第一个。
数字
仅更换数字正则表达式的第 次匹配。注意:posix 标准没有指定当你混合
g
和时会发生什么数字修饰符,目前在 sed 实现中还没有达成广泛一致的含义。对于 GNU sed,交互定义为: 忽略之前的匹配数字th,然后匹配并替换所有匹配项数字日。...
(强调我的)
答案3
我会分两步完成此操作:
首先,将所有分号替换为;NEW;
:
sed -e s/\;/\;NEW\;/g
;NEW;
然后用分号替换第一个:
sed -e s/\;NEW\;/\;/
您可以使用管道在一行上执行两项替换。这是一个例子:
$ more replacefile
india;austria;japan;chile;
china;US;nigeria;mexico;russia
$ cat replacefile |sed -e s/\;/\;NEW\;/g |sed -e s/\;NEW\;/\;/
india;austria;NEW;japan;NEW;chile;NEW;
china;US;NEW;nigeria;NEW;mexico;NEW;russia
答案4
我可以用更多代码来完成,但没有循环!
数据
china;US;nigeria;mexico;russia
iindia;austria;japan;chile
脚本
BEGIN{ FS=";" }{
insert=$param
ix=index($0, insert) + length(insert)
if (NF <= $param) {
rest = substr($0,ix,length($0))
gsub(";",";NEW;",rest)
line = substr($0,0,ix) rest
gsub(";;",";",line)
gsub(";$","",line)
print line
} else {print}}
例子
Microknoppix v # awk -f replaceNth.awk -v param=2 countries
china;US;NEW;nigeria;NEW;mexico;NEW;russia
iindia;austria;NEW;japan;NEW;chile