스크립트 에서 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 extglob
bash 또는 set -o kshglob
zsh 에서 ksh88 연산자에 대한 사전 지원이 필요합니다 .+([[:space:]])
또는 zsh
자신의 extendedglob
s( set -o extendedglob
)를 사용하십시오. 여기서 ksh는 다음 +(x)
과 같습니다 x##
.
var=${var//([[:space:]]##$word)##[[:space:]]##/ }
단어 앞이나 뒤의 공백을 복원하는 것도 가능합니다( zsh
bash가 아닌 ;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} )