문자열에서 단어의 다음 단어를 가져와야 합니다. 스크립트를 작성하려고 하는데 작동하지 않습니다. 이를 달성하기 위한 다른 대안을 제안해 주시면 좋을 것 같습니다.
스크립트:
#!/bin/bash
opts="OPTS=\"-name user -age 20 -where Asia -eats Brains\""
echo $opts
ok="0"
for word in $opts; do
if [ "$word" = "-where" ] ; then
if [ "$ok" = "1" ] ; then
echo $word
break
fi
ok="1"
fi
done
"-where"뒤에 단어를 얻고 싶습니다. 그러나 위의 스크립트는 작동하지 않습니다. 내가 무엇을 놓치고 있는지 이해하지 못합니다. 감사해요.
답변1
나는 grep
이 직책에 채용하는 것을 추천합니다:
$ OPTS="\"-name user -age 20 -where Asia -eats Brains\""
$ grep -Po -- '-where \K\w*' <<< "$OPTS"
Asia
설명하다:
-P
: Perl 호환 정규 표현식-o
: 일치하는 부분만 표시\K
: 해당 시점 이전의 모든 항목을 폐기합니다.\w*
: 일치 단어 구성 요소(의 동의어[_[:alnum:]]
)
"
일치하는 문자 목록에 추가하려면 :
$ grep -Po -- '-eats \K[_\"[:alnum:]]*' <<< $OPTS
Brains"
답변2
POSIX적으로:
after_first_where=${opts#*-where }
word_after_where=${after_first_where%% *}
또는 단어 사이에 공백을 허용하십시오.
after_first_where=${opts#*-where}
word_after_where=${after_first_where#"${after_first_where%%[![:blank:]]*}"}
word_after_where=${word_after_where%%[[:blank:]]*}
아니면 이렇게 할 수도 있습니다:
unset -v IFS; set -f # split on blanks, no glob
set -- $opts # splits $opts into $1, $2, $3...
while [ "$#" -ge 2 ]; do
case $1 in
(-age|-name|-where|-eats)
eval "${1#-}=\$2" # assigns name=$2 or where=$2...
shift 2;;
(*) shift
esac
done
printf '%s\n' "$name eats $eats in $where"
공백은 공백, 탭(및 줄 바꿈)으로 제한되며 [:blank:]
해당 지역에서 고려될 수 있는 다른 문자는 해당되지 않습니다.
답변3
스크립트를 일부 편집합니다.
#!/bin/bash
opts="OPTS=\"-name user -age 20 -where Asia -eats Brains\""
echo $opts
ok="0"
for word in $opts; do
if [ "$ok" = "1" ] ; then
echo $word
break
fi
if [ "$word" = "-where" ] ; then
ok="1"
fi
done
답변4
사용awk
opts="OPTS=\"-name user -age 20 -where Asia -eats Brains\""
awk '{for(i=1;i<=NF;i++) {if($i~"-where") {print $(i+1)}}}' <<< "$opts"
산출
Asia
사용 tr
및sed
tr ' ' '\n' <<< "$opts" | sed -n '/-where/{n;p}'
Asia
사용 tr
및awk
tr ' ' '\n' <<< "$opts" | awk '/-where/{getline;print;}'
Asia
tr ' ' '\n' <<< "$opts" | awk '/-where/{x=NR+1;next}(NR<=x){print}'
Asia