文字の最初のインスタンスのみを置き換える

文字の最初のインスタンスのみを置き換える

たとえば、次のscvファイルがあります。

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

私がしたいのは、最初のカンマを,セミコロンに置き換えることです;。最初のカンマの位置は可変です(行のa長さnm異なる場合があります)。最後に、私のファイルは次のようになります

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

他のカンマは維持する必要があります。誰かが私に最も簡単な解決策を教えてもらえますか?

PS私の解決策は動作しません。sed '/s/,/;/g' file.csv

答え1

中央g:

sed 's/,/;/g'

あるグローバルつまり、すべての項目を,に置き換えます;

1行に1つだけ交換する場合は、以下を省略してくださいg

sed 's/,/;/'

完全性のために:

交換する回数を指定することもできます。たとえば、2番目の項目のみを置き換えるには、次のようにします。

sed 's/,/;/2'

GNUを使用すると、sed2番目から始まるすべての項目(実際の最初の項目を除くすべての項目)を次に置き換えることもできます。

sed 's/,/;/2g'

この例では、2 つの置換を実行するには、次のようにします。

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

,replacementなど、パターンが置換(またはその一部)と一致できる場合、状況はさらに複雑になります<,>sedこの問題を解決するための組み込みメカニズムはありません。perlこの場合、次のものを代わりに使用できます。

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

perl -peperlのパターンは次のとおりですsed(正規表現の構文が異なることに注意してください)。演算子eフラグを使用すると、s///代替項目はコードと見なされます。ここでは、,増分カウンタ< 2の場合にのみ置き換えます。それ以外の場合はそれ自体を置き換えます(実際にはコマンドのように一致する文字列を参照してください)。<,>,$&&seds

これを一連の代替または代替セットに一般化できます。数字3〜5、7〜9同じです

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'

where startissendisです;。つまり、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)

関連情報