获取字符串中子字符串的下一个单词

获取字符串中子字符串的下一个单词

我需要获取字符串中单词的下一个单词。我试图编写一个脚本,但它不起作用。如果您建议我任何其他替代方案来实现这一目标,那就太好了。

脚本:

#!/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

POSIXly:

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

使用trsed

tr ' ' '\n' <<< "$opts" | sed -n '/-where/{n;p}'
Asia

使用trawk

tr ' ' '\n' <<< "$opts" | awk '/-where/{getline;print;}'
Asia

tr ' ' '\n' <<< "$opts" | awk '/-where/{x=NR+1;next}(NR<=x){print}'
Asia

相关内容