コマンドの出力を配列に保存する


23

これはコマンドです:pdc status -a 2>&1 | grep 'okay'次の出力を提供します

[okay     ]: you are currently listening: 33
[okay     ]: you are currently listening: 22
[okay     ]: you are currently listening: 11

このコマンドはシェルスクリプトファイルで記述しました。ただし、このコマンドの出力を配列に格納して、配列内の各インデックス値を処理します。

このコマンドの出力を配列に保存するにはどうすればよいですか?

回答:


24

各行の最後に数字が必要な場合:

numbers=( $(pdc ... | grep -oP 'okay.+?\K\d+$') )

各行を配列に保存する場合

mapfile -t lines < <(pdc ...)

配列からデータを取得するには:

for (( i=0; i<${#numbers[@]}; i++ )); do echo ${numbers[i]}; done
echo
printf "%s\n" "${lines[@]}"
33
22
11

[okay   ]: you are currently listening: 33
[okay   ]: you are currently listening: 22
[okay   ]: you are currently listening: 11

1
構文エラー:予期しないリダイレクト、私が使用してmapfile -t array < <(grep.....)
Sachith Muhandiram

bashまたは他のシェルを使用していますか?
グレンジャックマン

20

まず、出力を行ごとに処理するために、必ずしも配列が必要なわけではありません。

pdc status -a 2>&1 | grep 'okay' | while read line; do somecommand "$line"; done

配列が必要な場合は、Glenn Jackmanが既に最適な方法を提供してくれましたが、別のアプローチを次に示します。

#!/bin/bash
IFS=$'\n'
array=($(pdc status -a 2>&1 | grep 'okay'))

説明:

  • $IFS=$'\n'$IFSはbashの入力フィールド区切り文字であり、改行文字のみ(\n)に設定すると、出力行が空白で分割されなくなり、各行を個別の配列要素として保存できるようになります。これがないと、コマンドの出力の各単語は異なる要素になります。

    実行する内容によって$IFSは、配列の読み取り後に古い値を保存して復元することをお勧めします。

    oldifs="$IFS"
    IFS=$'\n'
    array=($(echo -e "foo bar\nbaz bar"))
    IFS="$oldifs"
  • $(command):これはコマンド置換と呼ばれ、コマンドの出力を変数に保存できます。これを行うには2つの方法があります。

    var=$(command)

    そして

    var=`command`

    2つのうち、次の$()理由により優れています。

    • ネストされたコマンドを処理できます。

      var=$(command1 $(command 2))

      例えば var=$(cat $(find ~/))

    • クォートに関する問題がはるかに少なく、構文が簡潔になります。詳細はこちらをご覧ください。


6

ビルトインを使用したさらに別のより直感的な方法readarray(を参照help -m readarray):

readarray -t array <<< "$(pdc status -a 2>&1 | grep 'okay')"

次に、配列要素を印刷するには、2番目の要素としましょう:

echo "${array[1]}"

すべての配列要素を別々の行に印刷するには、次を使用できます。

printf -- "%s\n" "${array[@]}"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.