正则表达式在Rubular中工作,但不在bash中

时间:2013-09-24 23:02:24

标签: regex string bash unix

给出一个字符串:

one/two one/three two/four five/six seven

我使用这个正则表达式:

(?<=\s)([^\/]*)(?=\/|\s)(?!.*\1\b)

得到:

one
two
five
seven

这是我想要的结果。所有独特的“根”字符串。它适用于Rubular,但bash不会返回任何匹配项。

我知道我正在使用的正则表达式包含一个感叹号,它会混淆bash,但在它前面添加一个斜杠转义字符没有帮助,也没有单引号。

我在这样的bash中使用它:

[[ $string =~ (?<=\s)([^\/]*)(?=\/|\s)(?!.*\1\b) ]] echo ${BASH_REMATCH}

我不能对正则表达式使用双引号,因为我使用的bash版本将双引号中的内容解释为文字字符串。

如何让bash理解这个正则表达式?

1 个答案:

答案 0 :(得分:2)

Bash肯定不了解perl兼容的正则表达式。我坚持用bash成语:

string="one/two one/three two/four five/six seven"
roots=$(sed 's/\/[^[:blank:]]*//g' <<< "$string" | tr ' ' '\n' | sort -u)
echo "$roots"

roots=()                        # empty array
for word in $string             # no quotes to obtain word splitting
do
    roots+=( ${word%/*} )       # add to the array the bit before the last slash
done
printf "%s\n" "${roots[@]}" | sort -u

或者,使用bash 4,使用关联数组来模仿集合的行为。

declare -A roots                # an associative array
for word in $string             # no quotes to obtain word splitting
do
    roots[${word%/*}]=1
done
printf "%s\n" "${!roots[@]}"    # print out the hash keys