Bestimmtes Wort in Variable entfernen

Bestimmtes Wort in Variable entfernen

Wie kann ich in einem bashSkript ein Wort aus einer Zeichenfolge entfernen? Das Wort würde in einer Variablen gespeichert.

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

Antwort1

Verwenden bashder Teilzeichenfolgenersetzung (kopiert aus ksh93):

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

Das //ersetzt alle Vorkommen der Teilzeichenfolge ( $WORDTOREMOVE) durch den Inhalt zwischen /und }. In diesem Fall nichts.

Beachten Sie die Anführungszeichen, $WORDTOREMOVEum sicherzustellen, dass der Inhalt als feste Zeichenfolge und nicht als Muster verstanden wird.

Wenn der Ersatz leer ist, /kann das auch weggelassen werden: ${FOO//"$WORDTOREMOVE"}.

Informationen hierzu und zu anderen Möglichkeiten, mit Strings in Bash zu arbeiten, finden Sie im Abschnitt10.1. Manipulation von ZeichenkettendesErweitertes Bash-Scripting-Handbuch.

Antwort2

Versuchen:

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

Dies funktioniert auch in ksh93(woher es kommt) mkshund zsh.


POSIXly:

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"

Es geht davon aus, dass Ihre Wörter durch Leerzeichen getrennt sind, und hat den Nebeneffekt, dass die Leerzeichen davor und danach entfernt werden "$WORDTOREMOVE".

Antwort3

Sie könnensedso was:

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

Antwort4

Entfernen einesWortaus einer Zeichenfolge, die eine durch Leerzeichen getrennte Liste von Wörtern darstellt, ist nicht so einfach, da Sie entscheiden müssen, was mit dem Abstand auf jeder Seite geschehen soll.

Selbst bei einer vereinfachten Darstellung, bei der zwischen den Wörtern immer ein einzelnes Leerzeichen steht, muss man zwischen mehreren Fällen unterscheiden:

  • Wort in der Mitte: foo MICE bar-> foo bar: Wort und die Leerzeichen davor und die Leerzeichen danach durch ein einzelnes Leerzeichen ersetzt.${var/+( )MICE+( )/ }
  • Wort am Anfang: MICE foo bar-> foo bar: Wort und die Leerzeichen danach durch nichts ersetzt:${var/MICE+( )}
  • Wort am Ende: foo bar MICE-> foo bar: Wort und die Leerzeichen davor durch nichts ersetzt: ${var/+( )MICE}.
  • dann gibt es das Problem, dass das Wort „where“ bei mehreren aufeinanderfolgenden Vorkommen ${var// MICE / }nicht funktionieren würde foo MICE MICE bar, da die erste Ersetzung den Platz vor dem zweiten „MICE“ beanspruchen würde.

(oben mit dem ${var/pattern/replacement}Operator aus ksh93).

Einfacher wird es allerdings, wenn Sie vor der Ersetzung am Anfang und am Ende ein Leerzeichen hinzufügen und diese anschließend wieder entfernen, da Sie dann alle Bereiche mit einem einzigen Ersetzungsoperator abdecken können:

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

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

Sie müssten shopt -s extglobin Bash oder set -o kshglobZsh vorher den KSH88-Operator unterstützen, +([[:space:]])um ein oder mehrere Leerzeichen abzugleichen.

Oder verwenden Sie zshdas eigene extendedglobs( set -o extendedglob), wo aus ksh +(x)Folgendes wird x##:

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

Es ist sogar möglich, den Abstand wiederherzustellen, der nach oder vor den Wörtern war (in zsh; ksh93 hätte etwas Entsprechendes, bash nicht):

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% }

Wenn Sie statt einer Skalarvariablen, die eine Darstellung einer Liste enthält, eine tatsächlicheListe(Array-)Variable, wie in:

var=(MICE foo MICE MICE bar MICE)

Dann reduziert sich das Problem auf das Entfernen bestimmter Elemente aus dem Array, was mit Shells mit richtigen Array-Variablen wie zsh(woher diese var=(foo bar)Syntax kommt) trivial wird:

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

verwandte Informationen