639

私のbashスクリプトには、文字列とそのプレフィックス/サフィックスがあります。元の文字列からプレフィックス/サフィックスを削除する必要があります。

たとえば、次の値があるとします。

string="hello-world"
prefix="hell"
suffix="ld"

次の結果を得るにはどうすればよいですか?

result="o-wor"
4

10 に答える 10

127

sed を使用:

$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

sed コマンド内では、^文字は で始まるテキストに一致$prefixし、末尾は$で終わるテキストに一致します$suffix

Adrian Frühwirth は、以下のコメントでいくつかの良い点を挙げていますがsed、この目的には非常に役立ちます。$prefix と $suffix の内容が sed によって解釈されるという事実は、良い場合も悪い場合もあります。注意を払っている限り、問題はありません。美しさは、次のようなことができることです:

$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

これはあなたが望むものかもしれません.bashの変数置換よりも洗練されており、より強力です. (スパイダーマンが言うように)大きな力には大きな責任が伴うことを覚えていれば、大丈夫です。

sed の簡単な紹介は、http://evc-cit.info/cit052/sed_tutorial.htmlにあります。

シェルとその文字列の使用に関する注意:

与えられた特定の例では、以下も同様に機能します。

$ echo $string | sed -e s/^$prefix// -e s/$suffix$//

...しかし、次の理由のみ:

  1. echo は引数リストに含まれる文字列の数を気にしません。
  2. $prefix と $suffix にスペースはありません

通常、コマンド ラインで文字列を引用符で囲むことをお勧めします。文字列にスペースが含まれていても、1 つの引数としてコマンドに提示されるからです。同じ理由で $prefix と $suffix を引用します: sed への各編集コマンドは 1 つの文字列として渡されます。変数の補間を可能にするため、二重引用符を使用します。一重引用符を使用した場合、sed コマンドはリテラル$prefixを取得し、$suffixこれは確かに私たちが望んでいたものではありません。

また、変数prefixと を設定するときに一重引用符を使用していることにも注意してくださいsuffix。確かに、文字列内の何も解釈されたくないので、それらを単一引用符で囲み、補間が行われないようにします。繰り返しますが、この例では必要ないかもしれませんが、身に付けるのは非常に良い習慣です。

于 2014-05-17T19:38:23.800 に答える
19

パスからプレフィックスを削除するためにgrepを使用します(これは ではうまく処理されませんsed):

echo "$input" | grep -oP "^$prefix\K.*"

\Kその前のすべての文字を一致から削除します。

于 2016-09-16T11:28:43.617 に答える
6

@Adrian Frühwirthの回答を使用:

function strip {
    local STRING=${1#$"$2"}
    echo ${STRING%$"$2"}
}

このように使用します

HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello
于 2017-02-08T06:47:59.820 に答える
0

正規表現でキャプチャ グループを利用します。

$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ set +H # Disables history substitution, can be omitted in scripts.
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/" <<< $string
o-wor
$ string1=$string$string
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/g" <<< $string1
o-woro-wor

((?:(?!(${suffix})).)*)${suffix}のコンテンツがキャプチャ グループから除外されることを確認します。例で言えば、 に相当する文字列です[^A-Z]*。それ以外の場合は、次のようになります。

$ perl -pe "s/${prefix}(.*)${suffix}/\1/g" <<< $string1
o-worldhello-wor
于 2019-10-02T09:26:41.887 に答える