次のコマンドを検討してください。
echo "string.with.dots" | sed 's/\(.*\)\.\(.*\)/\1\n\2/'
(最後の.
までの任意の文字を最初のキャプチャグループに一致させ、その後の文字を2番目のキャプチャグループに一致させます。)
この出力:
string.with
dots
適切な組み合わせでアンカーを使用すると、このような動作を逆転させることができると考えました(つまり、最初のキャプチャグループではstring
で、2番目のキャプチャグループではwith.dots
でした)。
echo "string.with.dots" | sed 's/^\(.*\)\.\(.*\)/\1\n\2/'
echo "string.with.dots" | sed 's/^\(.*\)\.\(.*\)$/\1\n\2/'
echo "string.with.dots" | sed 's/\(.*\)\.\(.*\)$/\1\n\2/'
すべての出力:
string.with
dots
パターンマッチングの実装方法はわかりませんが、文字列の末尾に近いパターンではなく、文字列の先頭に近いパターンに常に特権を与えているようです(^
が存在するか、$
が欠落しているにもかかわらず)。
どうすればこの動作を変更できますか(つまり、この例にハードコーディングされたソリューションを書く方法ではなく、パターンマッチングの優先順位をsed
または正規表現に逆にする方法) 、 可能なら?
2つのrev
を追加し、\1
と\2
を交換します。
echo "string.with.dots" | rev | sed 's/\(.*\)\.\(.*\)/\2\n\1/' | rev
出力:
string with.dots
必要なものを取得するには、これを試してください:
sed -r 's/^([^.]*)\.(.*)/\1\n\2/'
テスト:
$ echo "string.with.dots" | sed -r 's/^([^.]*)\.(.*)/\1\n\2/'
string
with.dots
sed
は貪欲に一致するため、sed 's/\(.*\)\.\(.*\)/\1\n\2/'
を使用している間は、最初のキャプチャグループとして最後の.
に貪欲に一致し、2番目として.
の後の残りに一致します。
sed
式で、sed
が欲張りになるのを止めるには、いくつかの代替案を検索する必要があります。最初から最初のグループ(.
)として[^.]*
に一致し、2番目として最初の一致後のものを一致させました。
.
の周りのすべての部分を別々の行にしたい場合:
$ echo "string.with.dots" | sed -r 's/^([^.]*)\.([^.]*)\.(.*)/\1\n\2\n\3/'
string
with
dots
Bash parameter expansion を使用して逃げることができるかどうか疑問に思います
$ s="string.with.dots"
$ echo "${s%%.*}"; echo "${s#*.}"
string
with.dots
$ echo "${s%.*}"; echo "${s##*.}"
string.with
dots