複数行の文字列変数内で最後に出現する文字を置き換えようとしています。
最後の|
を`
に置き換える必要があります。
rev
をパイプでつなぎ、最初のオカレンスを置き換えてから、もう一度rev
を介してパイプすることができます。
rev | sed -e 's/|/`/' | rev
または、純粋なsed
で、|
|
を含まないものが続くを`
に置き換え、その後に同じシーケンスを続ける必要があります。
sed -e 's/|\([^|]*\)$/`\1/'
それらの最初のものは読みやすく、理解しやすいと私は主張します。
.*
が貪欲であるという事実を利用できます。
sed 's/\(.*\)|/\1`/'
または使用:
sed 's/|\([^|]*\)$/`\1/'
Tobyがすでに示しているように、|
に続いて、|
を含まないものを行末まで一致させるには、このアプローチは1文字の置換に対してのみ機能します。
複数行の文字列シェル変数でGNU sed
に置き換えるには、入力を改行区切りではなくNUL区切りとして扱う-z
オプションを使用できます。
var=$(printf %s "$var" | sed -z '...')
別のアプローチは、標準のパラメーター展開演算子を使用して置換を行うことです。
case $var in
(*'|'*) var=${var%'|'*}'`'${var##*'|'}
esac
または、これらのsed
コマンドを同等のシェルに変換すると、次のようになります。
ksh93
:
var=${var/@(*)'|'/\1'`'}
var=${var/%'|'*([^'|'])/'`'\1}
bash
の場合(文字列に現在のロケールで有効な文字を形成していないバイトシーケンスが含まれていないと仮定):
re='(.*)\|(.*)'
[[ $var =~ $re ]] && var=${BASH_REMATCH[1]}'`'${BASH_REMATCH[2]}
zsh
:
set -o extendedglob
var=${var/(#b)(*)'|'/$match[1]'`'}
var=${var/%(#b)'|'([^'|']#)/'`'$match[1]}
$ printf '%s\n' "$str"
abc|def
ghi|jkl
$ printf '%s\n' "${str%\|*}"'`'"${str##*\|}"
abc|def
ghi`jkl
${str%\|*}
は、最後の|
とそれが削除された後のすべての文字列に展開されます。${str##*\|}
は、最後の|
とそれが削除される前のすべての文字列に展開されます。上記の2つのパラメーター置換を組み合わせて、`
を間にすると、結果の文字列が得られます。