変数から特定の単語を削除する

変数から特定の単語を削除する

スクリプトでbash変数に格納される文字列から単語を削除するにはどうすればよいですか?

FOO="CATS DOGS FISH MICE"
WORDTOREMOVE="MICE"

答え1

部分文字列置換を使用するbash(ksh93からコピー):

FOO=${FOO//"$WORDTOREMOVE"/}

//すべてのsubstring()エントリを$WORDTOREMOVEおよび間の内容に置き換えます。この場合は何もありません。/}

$WORDTOREMOVEコンテンツがパターンではなく固定文字列として扱われるように、二重引用符を確認してください。

スペースを置き換えるときは/省略することもできます${FOO//"$WORDTOREMOVE"}

これとbashで文字列を使用する他の方法については、セクションを参照してください。10.1。文字列操作~の高度なバッシュスクリプトガイド

答え2

努力する:

$ printf '%s\n' "${FOO//"$WORDTOREMOVE"/}"
CATS DOGS FISH

ksh93これは(ソース)mkshとにも当てはまりますzsh


フロント:

FOO="CATS DOGS FISH MICE"
WORDTOREMOVE="MICE"

remove_word() (
  set -f
  IFS=' '

  s=$1
  w=$2

  set -- $1
  for arg do
    shift
    [ "$arg" = "$w" ] && continue
    set -- "$@" "$arg"
  done

  printf '%s\n' "$*"
)

remove_word "$FOO" "$WORDTOREMOVE"

単語がスペースで区切られていると仮定し、前後のスペースを削除する副作用があります"$WORDTOREMOVE"

答え3

あなたはそれを使用することができますsedこのように:

echo $FOO | sed s/"$WORDTOREMOVE"//

答え4

一つ削除言葉スペースで区切られた単語のリストを表す文字列からデータを取得するのは簡単ではありません。各面の空白の処理方法を決定する必要があるからです。

単語の間に常にスペースがある普通の表現でも、いくつかのケースを区別する必要があります。

  • 中間の単語: foo MICE bar-> foo bar: 単語と前後の空白が空白一つに置き換えられます。${var/+( )MICE+( )/ }
  • 次に始まる単語: MICE foo bar-> foo bar: 単語とその後のスペースは空のスペースに置き換えられます。${var/MICE+( )}
  • 末尾の単語: foo bar MICE-> foo bar: 単語と前の空白は空の単語に置き換えられます: ${var/+( )MICE}
  • その後、最初の置換が2番目のMICEの前にスペースを占めるため、whereという単語が何度も連続して発生するという問題があります${var// MICE / }foo MICE MICE bar

(上記で${var/pattern/replacement}はksh93の演算子を使用します)。

ただし、交換を実行する前に、先頭と末尾にスペースを追加して後で削除すると簡単になります。これは、1つの置換演算子ですべての基盤をカバーできるためです。

var='MICE foo MICE MICE bar MICE'
word=MICE

var=" $var "
var=${var//+(+([[:space:]])"$word")+([[:space:]])/ }
var=${var# } var=${var% }

1つ以上の空白文字と一致するには、shopt -s extglobbashまたはset -o kshglobzshでksh88演算子の事前サポートが必要です。+([[:space:]])

またはzsh独自のextendedglobs(set -o extendedglob)を使用してください。ここでkshは次+(x)のようになりますx##

var=${var//([[:space:]]##$word)##[[:space:]]##/ }

単語の前または後の空白を復元することも可能です(zshbashではなく; ksh93に対応するエントリがあります)。

var='MICE foo MICE MICE bar MICE'
word=MICE

set -o extendedglob
var=" $var "
var=${var//(#b)([[:space:]]##$word)##([[:space:]]##)/$match[2]}
var=${var# } var=${var% }

リスト表現を含むスカラー変数ではなく、実際の変数がある場合リスト(配列)変数、例:

var=(MICE foo MICE MICE bar MICE)

その後、問題は配列から特定の要素を削除することになります。これは、次の適切な配列変数を持つシェルではマイナーなことですzshvar=(foo bar)この構文のソース)。

var=( ${var:#$word} )

関連情報