Sed:N個の文字を置き換えます。

Sed:N個の文字を置き換えます。

sedスクリプトの各行で最初の5つの空白文字を変更したいと思います。これが私が今まで持っているものです

sed -e "s/ /;/" -e "s/ /;/" -e "s/ /;/" -e "s/ /;/" -e "s/ /;/" myfile

もっと良い方法がありますか?

ところで、私はSolaris sedを使用しています。それが違いをもたらすかどうかはわかりません。

答え1

あなたの質問を読んで、少なくともGNU Sed(おそらくSolarisのものではないかもしれません)希望の逆機能:

g:最初の項目だけでなく、正規表現に一致するすべての項目に置換を適用します。

number: 正規表現の番号の一致のみを置き換えます。

Note: the posix standard does not specify what should happen when

現在、sed実装間で広く合意された意味のないgと数値修飾子を混在しています。 GNU sed の場合、相互作用は次のように定義されます。 3 番目の一致の前の一致を無視し、3 番目の一致以降のすべての一致を一致させ、置き換えます。

だから代わりに:

hmontoliu@ulises:/tmp/wb$ echo one two three four five six seven | sed 's/ /;/g5' 
one two three four five;six;seven

以下を実行して、必要なものを達成するためのより簡潔なコマンドを取得できます。

hmontoliu@ulises:/tmp/wb$ echo one two three four five six seven | sed -e 's/ /;/g' -e 's/;/ /6g'
one;two;three;four;five;six seven

Solarisの実装にこの機能があるかどうかを教えてください。

ファタイ

答え2

繰り返しのsedジャグリングを実行するよりも基本的なアイデアに固執する方が簡単です。おそらく、単純なforループを使用してパターンを構築すると、使いやすくなります。

pat=; for ((i=1; i<=5; i++)) ;do pat="$pat s/ /;/;"; done
sed -e "$pat" myfile

あるいは、複数の-e式オプションを削除し、;式の区切り文字ですべてグループ化するだけです。

sed -e "s/ /;/; s/ /;/; s/ /;/; s/ /;/; s/ /;/" myfile

これはsed-ただ一般的に気にしないバージョンですが、代替アイテムを好きなだけ指定できます。 (通過する{5})...

sed -nre ':check;G;/^.*\nx{5}$/{b print};s/^(.*)\n.*$/\1/;s/ /;/;t inc-tally;:print;P;x;s/.*//;x;b;:inc-tally;x;s/(.*)/\1x/;x;b check' myfile

~上一行(?)少し怖いので、ここにsedスクリプトファイルを介して呼び出される構造化コードがあります。sed -nrf "$fsed" myfile

:check             ## check the tally
 G                 ## pattern+=nl+hold
 /^.*\nx{5}$/{     ## we have the full complement of replacements
     b print       ## branch to print (and continue)
 }                 ##      
 s/^(.*)\n.*$/\1/  ##
 s/ /;/            ## change one space (if one is present) 
 t inc-tally       ## branch_on_substitute
:print             ## no more spaces to change
 P                 ## pattern_first_line_print
 x;s/.*//;x        ## kill the accumulated tally chars in hold   
 b                 ## branch to end of proc (continue)
:inc-tally         ##      
 x                 ## swap_pattern_and_hold
 s/(.*)/\1x/       ##
 x                 ## swap_pattern_and_hold
 b check           ## branch_unconditional 

関連情報