使用sed的后引用作为函数参数

时间:2015-03-25 12:32:43

标签: linux bash sed

我很难将sed的引用作为参数传递给函数。

这是一个例子

join() { sep="$1"; shift; echo -n "$1"; shift; printf "$sep%s" "$@"; }
index_of() {
  local value="${1}"
  shift
  local array=("${@}")
  for (( i = 0; i < ${#array[@]}; i++ )); do
    if [ "${array[$i]}" = $value ]; then
      echo $i
    fi
  done
}

array=('foo' 'bar' 'baz')
regex=$(join '\|' "${array[@]}")
echo 'baz' 'bar' 'foo' | sed "s/\(${regex}\)/[$(index_of "\1" ${array[@]})] \1/g"

我希望这会输出baz [2] bar [1] foo [0],但它会返回baz [] bar [] foo [],因为它会将'\1'作为值传递,而不是来自sed的匹配。

如何将实际匹配作为参数传递?

1 个答案:

答案 0 :(得分:1)

正如我评论的那样,你需要重新思考你是如何进行的。

这是重写:

index_of() {
    local value=$1 arrayname=$2    # we're passing the array by name
    local tmp="${arrayname}[@]"    # and then jumping through a hoop
    local array=("${!tmp}")        # to get the values

    # this is just a different way of iterating through the array
    local i=0
    for elem in "${array[@]}"; do
        if [[ $elem == $value ]]; then
            echo $i
            break       # save some time when a match is found
        fi
        ((i++))
    done
}

array=('foo' 'bar' 'baz')

# here's the big change: have to call the function in the same context
# as iterating through the words.
# in other words, call the shell function from the same shell
for word in baz bar foo; do
    printf "%s [%d] " "$word" $(index_of "$word" "array")
done

此外,效率更高join函数

join() { 
    local IFS="$1"
    shift
    echo "$*"
}