好奇的Bash模式替换行为

时间:2013-03-15 10:22:13

标签: bash

这个函数f()应该非常简单,但它以令人困惑的方式工作:

f() {
  a=(cyan red green blue orange violet)
  shopt -s extglob
  echo 1: -${a[@]/!($1)}-
  echo 2: -${a[@]/!($1)/}-
  echo 3: -${a[@]/!("$1")/}-
  echo 4: -"${a[@]/!($1)/}"-
  echo 5: -${a[@]/!($1)/x}-
}
echo ORANGE
f orange # ends in e like blue
echo YELLOW
f yellow

输出(请注意空白/间距):

ORANGE
1: - e -
2: - e -
3: - e -
4: -    e -
5: -x x x x xe x-
YELLOW
1: - -
2: - -
3: - -
4: -     -
5: -x x x x x x-

为什么所搜索单词的最后一个字符只是?! (在这种情况下为e的{​​{1}})

预期输出为orange,而不仅仅是orange

注意:在某些我看到一个空白的地方我也希望看到没有空白。

1 个答案:

答案 0 :(得分:2)

问题是模式没有锚定,因此例如对于orange,与orange不匹配的最长字符串是orang。因此将其删除,只剩e。由于无法如何在bash中指定锚点,您必须自己创建它们:

#! /bin/bash
f() {
    a=(cyan red green blue orange violet '1 2')
    a=("${a[@]/#/|}")
    a=("${a[@]/%/|}")
    shopt -s extglob
    echo ["${a[@]/|!($1)|/-}"]
}
echo ORANGE
f orange # ends in e like blue
echo YELLOW
f yellow