web-dev-qa-db-ja.com

ファイルからBash配列に行を読み込む

行を含むファイルを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を使っています

164

BinaryZebraのコメントからのコメントに基づく最新の改訂版はここでテストされていますcommand evalを追加すると、式を現在の実行環境に保持することができますが、前の式はevalの間だけ保持されます。

スペース\タブがない$ IFSを使用し、改行/ CRだけを使用してください。

$ 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の提案に従うこともでき、フォーク付きサブシェル+ catをで置き換えることもできます。

$(</etc/passwd)

私が時々使用する他のオプションは、単にIFSをXIFSに設定してから復元することです。これを気にする必要はありません Sorpigalの答え もご覧ください。

109
nhed

readarrayコマンド (やはりmapfileと表記)はbash 4.0で導入されました。

readarray a < /path/to/filename
203
chepner

ファイルの各行を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[@]}"
93
Sorpigal

Fileに各行1文字のスペースを含まない文字列が含まれている場合の代替方法

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

fileItemArray=($fileItemString)

チェック:

配列全体を印刷する:

${fileItemArray[*]}

Length=${#fileItemArray[@]}
18
Karanjot

あなたの最初の試みは終わりでした。これはあなたの考えを使った単純化したアプローチです。

file="somefileondisk"
lines=`cat $file`
for line in $lines; do
        echo "$line"
done
12
Atttacat
#!/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
2