변수에서 특정 단어 제거

변수에서 특정 단어 제거

스크립트 에서 bash문자열에서 단어를 어떻게 제거할 수 있습니까? 해당 단어는 변수에 저장됩니다.

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

답변1

하위 문자열 대체 사용 bash(ksh93에서 복사):

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

//모든 하위 문자열( )을 및 $WORDTOREMOVE사이의 내용으로 바꿉니다 . 이 경우에는 아무것도 없습니다./}

$WORDTOREMOVE내용이 패턴 대신 고정 문자열로 사용되는지 확인하려면 주변의 따옴표를 참고하세요 .

대체 항목이 비어 있으면 /생략할 수도 있습니다: ${FOO//"$WORDTOREMOVE"}.

이에 대한 정보와 bash에서 문자열을 사용하는 다른 방법은 섹션을 참조하세요.10.1. 문자열 조작~의고급 Bash 스크립팅 가이드.

답변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

하나 제거단어공백으로 구분된 단어 목록을 나타내는 문자열에서 각 측면의 공백으로 무엇을 할지 결정해야 하기 때문에 쉽지 않습니다.

단어 사이에 항상 단일 공백이 있는 길들여진 표현에서도 여러 가지 경우를 구별해야 합니다.

  • word in the middle: foo MICE bar-> foo bar: 단어와 앞의 공백, 뒤의 공백이 단일 공백으로 대체됩니다.${var/+( )MICE+( )/ }
  • 시작 부분의 단어: MICE foo bar-> foo bar: 단어와 그 뒤의 공백은 아무것도 없는 것으로 대체됩니다.${var/MICE+( )}
  • 끝에 있는 단어: foo bar MICE-> foo bar: 단어와 공백이 아무것도 없는 것으로 바뀌기 전: ${var/+( )MICE}.
  • 첫 번째 교체가 두 번째 MICE 앞의 공간을 차지하기 때문에 ${var// MICE / }작동하지 않는 단어가 여러 번 연속해서 나타나는 문제가 있습니다 .foo MICE MICE bar

( ${var/pattern/replacement}ksh93의 연산자를 사용하는 것 이상).

대체를 수행하기 전에 시작과 끝에 공백을 추가하고 나중에 제거하면 더 쉬워집니다. 그러면 하나의 대체 연산자로 모든 근거를 다룰 수 있습니다.

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

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

하나 이상의 공백 문자와 일치하도록 ksh88 연산자를 지원하려면 shopt -s extglobbash 또는 set -o kshglobzsh에서 미리 필요합니다 .+([[:space:]])

또는 zsh자신의 extendedglobs( set -o extendedglob)를 사용하면 ksh는 다음과 +(x)같이 됩니다 x##.

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

단어 앞이나 뒤의 공백을 복원하는 것도 가능합니다(in zsh; ksh93에는 bash가 아닌 동등한 것이 있을 것입니다).

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)

그런 다음 문제는 다음과 같은 적절한 배열 변수가 있는 쉘에서는 사소한 배열에서 특정 요소를 제거하는 것으로 줄어듭니다 zsh(해당 var=(foo bar)구문의 출처).

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

관련 정보