仅替换字符的第一个实例

仅替换字符的第一个实例

例如我有 scv 文件,看起来像

a1, b1, c1, d1
a2, b2, c2, d2
a3, b3, c3, d3

我想要做的是将第一个逗号替换,为分号;。第一个逗号的位置可以是可变的(a在行中n并且m可以有不同的长度)。最后我的文件看起来像

a1; b1, c1, d1
a2; b2, c2, d2
a3; b3, c3, d3

其他逗号必须保留。有人可以告诉我最简单的解决方案吗?

PS我的解决方案不起作用:sed '/s/,/;/g' file.csv

答案1

g

sed 's/,/;/g'

是为了全球,即将所有出现的 替换,;

如果您只想每行进行一次替换,请去掉g

sed 's/,/;/'

为了完整性:

您还可以指定要替换的出现次数。例如,仅替换第二次出现的情况:

sed 's/,/;/2'

使用 GNU sed,您还可以将从第二个开始的所有出现(实际上,除了第一个之外的所有出现)替换为:

sed 's/,/;/2g'

要执行两次替换,在本例中:

sed 's/,/;/;s/,/;/'

当模式可以匹配替换(或其部分)时,情况会变得更加复杂,例如用 替换,<,>sed没有内置机制来解决这个问题。perl在这种情况下,您可能想改用:

perl -pe '$i = 0; s/,/$i++ < 2 ? "<,>" : $&/ge'

perl -peisperlsed模式(请注意,正则表达式语法不同)。有了操作符e的标志s///,替换就被认为是代码。在那里,我们仅当增量计数器 < 2 时才替换,with 。否则,我们将替换为自身(实际上指的是匹配的字符串,如in的命令)。<,>,$&&seds

您可以将其概括为一系列或一组替换。就像第 35 个第 79一样:

perl -pe '$i = 0; s/,/$i++;
   $i >=3 && $i <= 5 || $i >= 7 && $i <= 9 ? "<,>" : $&/ge'

仅替换第一次出现的位置在整个输入中(相对于在每一行):

sed -e 's/,/;/;t done' -e b -e :done -e 'n;b done'

也就是说,在第一次成功替换后,进入一个仅打印其余输入的循环。

使用 GNU sed,您可以使用伪地址0:

sed '0,/,/s//;/'

笔记

我想这是一个错字,但是

sed '/s/,/;/g'

你在问题中写的命令是完全不同的。

那是在做:

sed '/start/,/end/g'

哪里startsend;.也就是说,g对文件中包含 的部分s和下一个包含;.

答案2

纯的巴什解决方案

while IFS=\, read -r a b ; do echo "$a;$b" ; done <file.csv

或者只是为了好玩

paste -d\; <(cut -d, -f1 file.csv) <(cut -d, -f1 --complement file.csv)

相关内容