繰り返される文字の間に文字を挿入します。

繰り返される文字の間に文字を挿入します。

文字列が与えられたら、カンマの前に文字がなく、文字がない各コンマの間に最初に強制的に適用したいと,,a,,,b,,,,思います。-結果は次のとおりです-,-,a,-,-,b,-,-,-,-

echo ",,a,,,b,,,," | sed 's/,/,-/g' | sed 's/-\([^,]\)/\1/g' | sed 's/^,/-&/g'

次に続く:-,-,a,-,-,b,-,-,-,-

しかし、問題は、sedを3回呼び出すことが非常に非効率的であるということです。非常に長い反復sedでこれを行う方法はありますか?正規表現、または他のツール一度電話してください

答え1

(echo ,,a,,,b,,,,; echo a,,b) | perl -pe 's/(^|,)\K(?=(,|$))/-/g' 
-,-,a,-,-,b,-,-,-,-
a,-,b

sed今年の一学期勉強しなければならないと思います。

答え2

一つこれを行う方法はsedループを使用することです。

$ echo ",,a,,,b,,,," | sed ':a; s/\(^\|,\)\(,\|$\)/\1-\2/; ta'
-,-,a,-,-,b,-,-,-,-

あなたのバージョンが拡張正規表現をサポートしている場合は、読みやすくするために簡単にすることができます。

sed -E ':a; s/(^|,)(,|$)/\1-\2/; ta'

別の方法は、でこれを行い、カンマ区切りのperlフィールドに分割し、空のフィールドをハイフンにマップすることです。

perl -anle 'print join ",", map { $_ ? $_ : "-" } split(",", $_, -1)'

(末尾の空のフィールドを含む追加のパラメータを強制します-1)。split

答え3

echo ",,a,,,b,,,," |
  awk -v 'FS=,' -v 'OFS=,' '{for (i=1; i<=NF; i++) sub(/^$/,"-",$i); print};'

答え4

$ echo ',,a,,,b,,,,' | sed 's/\(\([^,]\+,\)*\),/\1-,/g; s/\(^\|,\)$/\1-/'
-,-,a,-,-,b,-,-,-,-

2番目の式()は、パターンスペースの終わりに達すると一致を停止するように見えるs/\(^\|,\)$/\1-/ため、必要です。唯一の式があれば、まだaと一致するかもしれませんが、それは言葉です。sed$s/\(\([^,]\+,\)*\)\(,\|$\)/\1-\3/g

もちろん、sed -Eこれは読みやすくなりますが、他の点では同じです。

sed -E 's/(([^,]+,)*),/\1-,/g; s/(^|,)$/\1-/'

関連情報