2015-03-25 56 views
0

我很努力地將sed的引用作爲參數傳回給函數。使用sed的後端引用作爲函數參數

下面是一個例子

join() { sep="$1"; shift; echo -n "$1"; shift; printf "$sep%s" "[email protected]"; } 
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比賽。

如何將實際匹配作爲參數傳遞?

+0

由於[順序擴展的](https://www.gnu.org/software/bash /manual/bashref.html#Shell-Expansions),** sed啓動之前正在執行命令替換**。 – 2015-03-25 18:11:32

回答

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 "$*" 
} 
+0

謝謝,我想我必須在這裏改變我的方法 – shime 2015-03-27 10:24:47