2016-12-19 9 views
1

私は必要に応じてeasly文字列を配列に変換する関数を作成しています。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[@]}" 

また、アレイに結果を保存することができます、あなたは、sedここcutを使用する必要はありませんそれだけで十分です。

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 ]を参照してください。

警告:出力は1つの形式でもかまいません。 ($(..))は、comment#1に指摘されているような反パターンですが、この場合は十分です。

+1

コマンド置換を二重引用符で囲むことにより、意図していない_all lines_を含む_single_要素を持つ配列が作成されます。二重引用符を使用しない場合、出力行は常に単語分割とglobbingの対象となりますが、そのような場合には動作しますが、 '($(...))'はコマンド出力を読み込む一般的な方法ではありません配列( '$ IFS'を設定してglobbingをオフにしない限り、これは有効ではありません)。 – 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[@]}" 

convert2array内部

  • $1は、あなたの入力変数、$mx名前ではありませんが、その
    宣言したい変数の名前を、(入力名を変更した後に)明示的に別の引数として渡す必要があります。デフォルトで

  • readあなたは複数ラインを渡しているのに対してのみ、入力の第一行を読み込みます。
    -d ''read全て行を読み取ることができる、とIFS=$'\n'read全体として各行を読み取ることができます。
    Bash v4 +では、組み込みのreadarrayを使用して、IFS=$'\n' read -d '' -rareadarray -tに置き換えることができます。

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

    Bashのバージョン3.xの代替:


あなたのコマンドの合理化されたバージョンは、BashのV4 + readarray組み込みを使用して、配列に直接dig ...出力ラインを読むことであろう:

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

あなたの関数で何が悪かったのかに注意してください。

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を他に必要なものにパイプしてください。


注:上記のコードはsedcutを回避するために、単純なその場しのぎが含まれている - だけではなく、出力のみ偶数アレイメンバー、およびparameter expansionを使用する「最小サフィックスパターンを削除する」ことを削除するには ' 。最後に。

関連する問題