2011-07-23 29 views
0

我已成功製成的聯接函數,使用定界符它連接一個數組爲字符串:用含有元素空格對外輸出陣列

function join() # Usage: string=$(join "delimeter" "${array[@]}") 
{ 
    local array=("${@:2}") 
    OLD_IFS="$IFS" 
    IFS="$1" 
    local string="${array[*]}" 
    IFS="$OLD_IFS" 
    echo "$string" 
} 

我也試圖使分裂函數應該做相反的:

function split() # Usage: array=($(split "delimeter" "$string")) 
{ 
    OLD_IFS="$IFS" 
    IFS="$1" 
    local array=($2) 
    IFS="$OLD_IFS" 
    echo "${array[@]}" 
} 

但是,當我使用split命令並且結果包含空格時,它將無法按預期工作。 實施例:

array=("foo" "bar" "baz" "foo bar") 
string=$(join "|" "${array[@]}") 
echo $string 
array=($(split "|" "$string")) 
for i in ${array[@]} 
do 
    echo $i 
done 

的最後一個元素爲 「foo欄」 已拆分過。 我認爲解決方案是你必須做array=("$(split '|' "$string")"),但我不知道如何嵌套報價。

回答

3

注意,IFS可以在一個局部變量一個功能,所以你不必備份和恢復它的值:

join() { local IFS="$1"; local s="${@:2}"; printf "%s" "$s"; } 

這裏是分裂的實現需要一個eval:

# usage: split varName separator stringToSplit 
split() { 
    local var="$1" 
    local IFS="$2" 
    set -- $3 
    echo "declare -a $var=($(printf "\"%s\" " "[email protected]"))" 
} 

示範

$ a=(foo bar "hello world" baz) 
$ s=$(join , "${a[@]}") 
$ echo $s 
foo,bar,hello world,baz 
$ split b , "$s" 
declare -a b=("foo" "bar" "hello world" "baz" ) 
$ eval $(split b , "$s") 
$ for x in "${b[@]}"; do echo "$x"; done 
foo 
bar 
hello world 
baz 
2

問題出在split()函數的末尾。您將數組序列化回字符串!所以它又被字符串分隔了空格,它不能識別空格是否在項目內。所以,我知道它並不是很乾淨,但是您必須使用全局變量返回split()函數的值(在示例中省略關鍵字local並簡化調用,並且雙引號至for命令以及一些其他化妝品的變化和它的作品...:

function split() # Usage: array=($(split "delimeter" "$string")) 
{ 
    OLD_IFS="$IFS" 
    IFS="$1" 
    array2=($2) 
    IFS="$OLD_IFS" 
} 


array=("foo" "bar" "baz" "foo bar") 
string=$(join "|" "${array[@]}") 
echo $string 
split "|" "$string" 
for i in "${array2[@]}" 
do 
    echo $i 
done 

不知道是否有清潔的方式,避免了全局變量,但我懷疑