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