2016-04-19 7 views
1

ファイルから配列を取り込むことは基本的なものですが、動作させることはできません。ファイルの行をbash配列に代入する方法

#!/bin/bash 
    declare -a a 
    i=0 
    cat "file.txt" | while read line; do 
     a[$i]="$line" 
     i=$(($i + 1)) 
    done 
    echo "${a[0]}" 

これは、空の行を印刷します。ライン「foo」と「bar」を含むファイルの場合は、ここではbash -xからの出力です:

+ declare -a a 
    + i=0 
    + cat file.txt 
    + read line 
    + a[$i]=Foo 
    + i=1 
    + read line 
    + a[$i]=Bar 
    + i=2 
    + read line 
    + echo '' 

私もreadarray組み込み作業を取得することはできません。

#!/bin/bash 
    declare -a b 
    cat "file.txt" | readarray b 
    echo "${b[0]}" 

    + declare -a b 
    + cat file.txt 
    + readarray b 
    + echo '' 

は何午前私はここで間違っている?

答えて

3

これは基本的なbash落とし穴です:パイプラインのすべてのセグメントがデフォルトでサブシェルで実行し、これらのサブシェルが終了したときに、彼らが作るどんな変数がスコープの外に出ることを意味します(現在のシェルがそれらを表示されません) 。

あなたが使用しているbashのバージョンに応じて、2つのオプションがあります。

  • を[Bashのv4.2のが+]あなたは最後のパイプライン・セグメントことを確認するために、パイプラインを使用する前にshopt -s lastpipeを実行します現在のシェルで実行されます。あなたのwhileループはサブシェルで実行されないことを確実にする代わりに、パイプライン(または、より複雑な例では、プロセス置換(<(...))の

  • 使用入力リダイレクション(<):

ファイルから行を読み取る単純なケースで
a=() 
while IFS= read -r line; do 
    a+=("$line") 
    # ... 
done < "file.txt" 

、あなたは配列に直接を読むことができます("${a[@]}"、この例では):

  • バッシュ4.xの:

    • readarray -t a < "file.txt"
  • 以前のバージョン:

    • IFS=$'\n' read -r -d '' -a a < "file.txt"
+2

読書のための第二次資料:http://mywiki.wooledge.org/BashPitfalls – kojiro

+1

これは非常に便利であることが約束されています。ありがとうございました! – marshallm

関連する問題