2016-12-19 50 views
1

我正在做一個函數來輕鬆地將我的字符串轉換爲數組,作爲我需要的。在bash中的一個函數中設置位置參數

我有點遇到一個奇怪的問題。我對bash仍然陌生,這真的讓我感到困擾。任何人都可以對此有所瞭解嗎?

convert.sh

#!/bin/bash 
convert2array() { 
read -a $1_arr <<< $1 
} 

mx=$(dig +short google.com mx | cut -d' ' -f 2 | sed 's/\.$//') 

convert2array "$mx" 

echo ${mx_arr[@]} 

輸出:

bash -x convert2array.sh 
++ sed 's/\.$//' 
++ cut '-d ' -f 2 
++ dig +short google.com mx 
+ mx='alt2.aspmx.l.google.com 
alt3.aspmx.l.google.com 
alt1.aspmx.l.google.com 
aspmx.l.google.com 
alt4.aspmx.l.google.com' 
+ convert2array mx 
+ read -a mx_arr 
+ echo 585911 
585911 

回答

2

您可以結果直接存儲在陣列中

declare -a results=($(dig +short google.com mx | cut -d' ' -f 2 | sed 's/\.$//')) 
echo "${results[@]}" 

而且,你不必使用cut這裏,sed單獨就足夠了。

declare -a results=($(dig +short google.com mx | sed -E 's/^[[:digit:]]*[[:blank:]]*(.*)\.$/\1/')) 
echo "${results[@]}" 
aspmx.l.google.com 
alt1.aspmx.l.google.com 
alt2.aspmx.l.google.com 
alt4.aspmx.l.google.com 
alt3.aspmx.l.google.com 

[ bash arrays ][ command subsctitution ][ positional parameters ]

您被警告:輸出可能只是一種格式。雖然($(..))comment#1中指出的反模式,但對於這種情況,這就足夠了。

+1

通過雙引號替換你總是創建一個_single_元素包含_all lines_的數組,這不是意圖。如果沒有雙引號,輸出行總是受到分詞和匹配的影響,即使這種情況在_this_情況下可行,'($(...))'也不是一種將命令輸出讀入一個數組(除非你設置'$ IFS'並關閉通配符,這是不值得的)。 – mklement0

+0

@ mklement0:感謝您的指針。我想了一下,但後來忘了把這個雙引號趕緊發表一個答案:)現在更改 – sjsam

+0

@ mklement0:另外,我同意你的評論的第二部分 – sjsam

3

嘗試以下操作:

convert2array() { 
    # Bash v4+ alternative: `readarray -t` instead of `IFS=$'\n' read -d '' -ra` 
    IFS=$'\n' read -d '' -ra "$1" <<<"$2" 
} 

mx=$(dig +short google.com mx | cut -d' ' -f 2 | sed 's/\.$//') 

convert2array mx_arr "$mx" 

printf '%s\n' "${mx_arr[@]}" 

至於你嘗試過什麼:

  • $1convert2array不是名稱的輸入變量的$mx,但其
    您需要顯式地傳入要聲明的變量的名稱(可能在修改輸入名稱後),作爲單獨的參數。

  • read默認只讀取線輸入的,而你傳遞線。
    -d ''使得read所有線,並且使得IFS=$'\n'read每一行整體
    在Bash v4 +中,使用內建readarray,IFS=$'\n' read -d '' -ra可以替換爲readarray -t


您的命令的精簡版本將是直接讀取dig ...輸出線到一個數組,使用擊V4 + readarray內置:

readarray -t mx_arr < <(dig +short google.com mx | cut -d' ' -f 2 | sed 's/\.$//') 

擊V3.x的替代:

IFS=$'\n' read -d '' -ra mx_arr < <(dig +short google.com mx | cut -d' ' -f 2 | sed 's/\.$//') 
1

Just a注意在什麼地方出了問題你的函數:

convert2array() { 
read -a $1_arr <<< $1 
} 

在這裏,你正在閱讀在$1的內容,這是變量的名稱,當你想讀變量本身的內容。你可以在這裏使用間接:

convert2array() { 
    read -a $1_arr <<< ${!1} 
} 

正如其他人所指出的那樣,有更容易的方式來獲得在陣列的輸出。

0

提供的陣列僅僅是一次性的,用於只讀輸出迴路,POSIX殼可以做到這一點:

set -- `dig +short google.com mx` ; \ 
while [ "$2" ] ; do echo "${2%.*}" ; shift 2 ; done 

輸出:

alt2.aspmx.l.google.com 
alt3.aspmx.l.google.com 
alt4.aspmx.l.google.com 
alt1.aspmx.l.google.com 
aspmx.l.google.com 

如果輸出需要更進一步地大驚小怪,將echo管到任何其他需要做的事情上。


注:上述代碼包含一個簡單的kludge避免sedcut - 而不只是僅輸出偶數陣列成員,並使用parameter expansion刪除最小匹配模式」以刪除' 「。最後。

相關問題