仅替换字符的第一个实例

Guf*_*oru 5 sed text-processing csv

例如我有一个看起来像的 scv 文件

a1, b1, c1, d1
a2, b2, c2, d2
a3, b3, c3, d3
Run Code Online (Sandbox Code Playgroud)

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

a1; b1, c1, d1
a2; b2, c2, d2
a3; b3, c3, d3
Run Code Online (Sandbox Code Playgroud)

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

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

Sté*_*las 16

g在:

sed 's/,/;/g'
Run Code Online (Sandbox Code Playgroud)

用于全局,即替换所有出现的,with ;

如果您只想每行进行一次替换,请取消g

sed 's/,/;/'
Run Code Online (Sandbox Code Playgroud)

为了完整性:

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

sed 's/,/;/2'
Run Code Online (Sandbox Code Playgroud)

使用 GNU sed,您还可以用以下内容替换从第二个开始的所有事件(实际上,除了第一个之外的所有事件):

sed 's/,/;/2g'
Run Code Online (Sandbox Code Playgroud)

要执行两个替换,在这种情况下:

sed 's/,/;/;s/,/;/'
Run Code Online (Sandbox Code Playgroud)

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

perl -pe '$i = 0; s/,/$i++ < 2 ? "<,>" : $&/ge'
Run Code Online (Sandbox Code Playgroud)

perl -peisperlsed模式(注意正则表达式的语法是不同的)。带有操作符的e标志s///,替换被认为是代码。在那里,我们更换,<,>只有当我们增加计数器是<2。否则,我们更换,与本身($&实际上指的是匹配的字符串像&seds命令)。

您可以将其概括为一系列或一组替换。像为3〜5和7至9

perl -pe '$i = 0; s/,/$i++;
   $i >=3 && $i <= 5 || $i >= 7 && $i <= 9 ? "<,>" : $&/ge'
Run Code Online (Sandbox Code Playgroud)

仅替换整个输入中的第一次出现(而不是在每一行中):

sed -e 's/,/;/;t done' -e b -e :done -e 'n;b done'
Run Code Online (Sandbox Code Playgroud)

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

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

sed '0,/,/s//;/'
Run Code Online (Sandbox Code Playgroud)

笔记

我想这是一个错字,但

sed '/s/,/;/g'
Run Code Online (Sandbox Code Playgroud)

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

这样做:

sed '/start/,/end/g'
Run Code Online (Sandbox Code Playgroud)

这里startsend;。也就是说,应用g命令(替换保留空间的内容模式空间(空这里你永远不嫌弃))的文件的部分在一个包含之间s和包含下一个;


Cos*_*tas 3

bash解决方案

while IFS=\, read -r a b ; do echo "$a;$b" ; done <file.csv
Run Code Online (Sandbox Code Playgroud)

或者只是为了好玩

paste -d\; <(cut -d, -f1 file.csv) <(cut -d, -f1 --complement file.csv)
Run Code Online (Sandbox Code Playgroud)