241

行を含むファイルを Bash 配列に読み込もうとしています。

これまでに次のことを試しました。

試行1

a=( $( cat /path/to/filename ) )

試行2

index=0
while read line ; do
    MYARRAY[$index]="$line"
    index=$(($index+1))
done < /path/to/filename

どちらの試みも、ファイルの最初の行を含む 1 つの要素の配列のみを返します。私は何を間違っていますか?

私はbash 4.1.5を実行しています

4

6 に答える 6

347

このreadarrayコマンド(スペルもmapfile) は、bash 4.0 で導入されました。

readarray -t a < /path/to/filename
于 2012-07-09T12:38:41.527 に答える
141

BinaryZebraのコメントからのコメントに基づいており、ここ でテストされた最新のリビジョン。を追加command evalすると、式を現在の実行環境に保持できますが、前の式は評価期間中のみ保持されます。

スペースやタブがなく、改行/CRだけの$IFSを使用します

$ IFS=$'\r\n' GLOBIGNORE='*' command eval  'XYZ=($(cat /etc/passwd))'
$ echo "${XYZ[5]}"
sync:x:5:0:sync:/sbin:/bin/sync

また、配列は問題なく設定されているかもしれませんが、読み方が間違っている可能性があることに注意してください。上記の例のように、必ず二重引用符""と中括弧の両方を使用してください。{}


編集:

グロブ拡張の可能性についてのコメント、特に以前の回避策についてのgniourf-gniourfのコメントで、私の回答に関する多くの警告に注意してください。

これらすべての警告を念頭に置いて、私はまだこの答えをここに残しています(はい、bash 4は何年も前から出ていますが、2/3年しか経っていない一部のMacがデフォルトのシェルとしてpre-4を持っていることを思い出します)

その他の注意事項:

以下のdrizztの提案に従い、フォークされたサブシェル+猫を次のように置き換えることもできます

$(</etc/passwd)

私が時々使用する他のオプションは、IFSをXIFSに設定し、後で復元することです。これを気にする必要のないSorpigalの答えも参照してください。

于 2012-07-09T11:10:02.027 に答える
136

ファイルの各行をbash配列に読み込む最も簡単な方法は次のとおりです。

IFS=$'\n' read -d '' -r -a lines < /etc/passwd

次に、配列にインデックスを付けて、lines各行を取得します。

printf "line 1: %s\n" "${lines[0]}"
printf "line 5: %s\n" "${lines[4]}"

# all lines
echo "${lines[@]}"
于 2012-07-09T11:20:55.977 に答える
25

ファイルに各行に 1 文字列のスペースのない文字列が含まれている場合の別の方法:

fileItemString=$(cat  filename |tr "\n" " ")

fileItemArray=($fileItemString)

小切手:

配列全体を出力:

${fileItemArray[*]}

Length=${#fileItemArray[@]}
于 2013-10-21T12:47:30.840 に答える
23

あなたの最初の試みは間近でした。これがあなたのアイデアを使った単純なアプローチです。

file="somefileondisk"
lines=`cat $file`
for line in $lines; do
        echo "$line"
done
于 2015-05-29T17:51:23.007 に答える
4
#!/bin/bash
IFS=$'\n' read  -d '' -r -a inlines  < testinput
IFS=$'\n' read  -d '' -r -a  outlines < testoutput
counter=0
cat testinput | while read line; 
do
    echo "$((${inlines[$counter]}-${outlines[$counter]}))"
    counter=$(($counter+1))
done
# OR Do like this
counter=0
readarray a < testinput
readarray b < testoutput
cat testinput | while read myline; 
do
    echo value is: $((${a[$counter]}-${b[$counter]}))
    counter=$(($counter+1))
done
于 2014-04-18T19:35:00.760 に答える