짧은 옵션 문자열과 긴 옵션 문자열로 분할하려는 짧은 옵션 문자열이 있습니다.
opts="-p,--plong,--pext"
내 생각은 짧은 옵션에 문제가 있는 grep을 사용하는 것입니다.
opts="-p,--plong,--pext"
short_opts=$(echo "$opts" | grep -o '\s*-\w*')
long_opts=$(echo "$opts" | grep -o '\s*--\w*')
echo
echo "short_opts: $short_opts"
echo "long_opts: $long_opts"
답변1
Bash 대신 zsh에서는 다음을 수행할 수 있습니다.
opts="-p,--plong,--pext"
# split on ,s into an array
opts=( ${(s[,])opts} )
short_opts=( ${opts:#--*} )
long_opts=( ${(M)opts:#--*} )
그런 다음 두 개의 배열을 얻습니다.
$ typeset -p short_opts long_opts
typeset -a short_opts=( -p )
typeset -a long_opts=( --plong --pext )
-
짧은 옵션만 허용하고 그 뒤에 하나를 제외한 모든 문자가 오는 -
것과 긴 옵션 --
뒤에 다음을 제외한 하나 이상의 문자가 오는 등 보다 제한적인 일치를 만들려면 다음을 사용하세요 =
.
set -o extendedglob
short_opts=( ${(M)opts:#-[^-]} )
long_opts=( ${(M)opts:#--[^=]##} )
s
bash에는 분할 연산자( 위의 zsh 인수 확장 플래그 와 같은)가 없지만 Bourne 쉘에서 상속된 인용되지 않은 확장에 대해 악명 높은 분할+glob을 수행합니다. 따라서 이것을 사용하여 분할을 수행할 수 있습니다.
IFS=, # split on ,
set -o noglob
opts=( $opts )
zsh 연산자와 같은 배열 필터 연산자 는 없지만 ${array:#pattern}
ksh93의 배열 멤버 편집 연산자가 있으며 ${array[@]/pattern/replacement}
따옴표가 없는 확장은 빈 요소를 제거하므로 그렇게 할 수 있습니다( noglob
여전히 열려 있고 $IFS
비어 있거나 여전히 단지 include 라고 가정 ,
).
short_options=( ${opts[@]/#--*} )
long_options=( ${opts[@]/#-[!-]*} )
#
처음에 패턴을 고정하십시오. %
끝에 앵커를 지정하지만 zsh와 달리 bash는 시작과 끝에서 앵커를 지원하지 않으므로 요소 전체를 일치시킬 수 없습니다. case
더 엄격한 일치가 필요한 경우 언제든지 모든 요소를 반복하여 일치에 사용할 수 있습니다.
short_opts=() long_opts=()
shopt -s extglob
for opt in "${opts[@]}"; do
case $opt in
( -[^-] ) short_opts+=( "$opt" );;
( --+([^=]) ) long_opts+=( "$opt" );;
esac
done
ksh와 마찬가지로 bash는 의미를 구분 기호 $IFS
에서 S
구분 기호/종료 기호로 변경합니다. 즉 , 빈 문자열 a,,b,
로 분할 되고 추가 빈 문자열이 없음을 의미합니다. 모든 요소가 옵션이었다면 여기서는 문제가 되지 않을 것입니다.a
b
답변2
나는 이미 이것을 했다
opts="-p,--plong,--pext"
for opt in ${opts//,/ }; do
if [[ "$opt" == --* ]]; then
long_opts="$long_opts $opt"
elif [[ "$opt" == -* ]]; then
short_opts="$short_opts $opt"
fi
done
echo
echo "short_opts: $short_opts"
echo "long_opts: $long_opts"