변수에서 특정 단어 제거

변수에서 특정 단어 제거

스크립트 에서 bash변수에 저장될 문자열에서 단어를 제거하려면 어떻게 해야 합니까?

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

답변1

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

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

//모든 substring() 항목을 $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

하나 삭제단어공백으로 구분된 단어 목록을 나타내는 문자열에서 데이터를 가져오는 것은 쉽지 않습니다. 각 면의 공백을 처리하는 방법을 결정해야 하기 때문입니다.

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

  • 중간에 있는 단어: foo MICE bar-> foo bar: 단어와 앞뒤 공백이 공백 하나로 대체됩니다.${var/+( )MICE+( )/ }
  • 다음으로 시작하는 단어: MICE foo bar-> foo bar: 단어와 그 뒤의 공백은 빈 공백으로 대체됩니다.${var/MICE+( )}
  • 끝에 있는 단어: foo bar MICE-> foo bar: 단어와 앞의 공백은 빈 단어로 대체됩니다: ${var/+( )MICE}.
  • 그런 다음 첫 번째 대체가 두 번째 MICE 이전에 공간을 차지하기 때문에 where라는 단어가 여러 번 연속해서 발생하는 문제가 있습니다 ${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% }

하나 이상의 공백 문자와 일치하려면 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)

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

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

관련 정보