2012-07-05 14 views
27

可能性の重複:
Looping through the content of a file in Bash?シェルを使用して外部ファイルの行を繰り返し処理するにはどうすればよいですか?

私は名前のリストで一つのファイルを持っています。このファイル内のすべての名前をシェルスクリプトで外部ファイルからループする必要があります。どうやってやるの?

例ファイル:

スクリプト/ names.txt

alison 
barb 
charlie 
david 

スクリプト/ script.sh私は別々に配列にnames.txtファイルを爆発するにはどうすればよい

NAMES="" #names from names.txt file 
for NAME in $NAMES; do 
    echo "$NAME" 
done 

シェルスクリプト?

+1

どのように? – bearvarine

答えて

54

一つの方法の値を変えることができるものの...この問題を回避しますreadを使用すると、次のようになります。

while read NAME 
do 
    echo "$NAME" 
done < names.txt 

EDIT:ループがサブで実行されることを 注意したがって、ループの外に declareで宣言した場合を除いて、変更された変数はすべてローカルになります。

デニスウィリアムソンが正しいです。申し訳ありませんが、パイプ構造を頻繁に使用して、混乱しているに違いありません。

+2

いいえ、何も 'while'にパイプされていないので、サブシェルはありません。 'done'へのリダイレクションはサブシェルを作成しません。 –

+0

ちなみに、kornシェルではパイプでの問題(バグ?)は発生しません(しかし、pdkshではそうです)。 – cdarke

5

私は純粋主義者がこの方法を嫌うだろうと知っていますが、あなたはcatファイルです。

NAMES=`cat scripts/names.txt` #names from names.txt file 
for NAME in $NAMES; do 
    echo "$NAME" 
done 
+5

これは、サブシェルを呼び出さないという利点がありますが、 'names.txt'内のスペースは区切り文字としてみなされます。 – smocking

+2

「純粋主義者」は、これに間違っていることを説明するのに役立ちます。複数の問題があります。 read line中にhttp://mywiki.wooledge.org/DontReadLinesWithFor – tripleee

6
cat names.txt|while read line; do 
    echo "$line"; 
done 
+4

'を参照してください。行う ...; done

13

あなたは「$名は」引用されているというコマンドを「読み取り」

while read name 
do 
    echo "$name" 
done < names.txt 

注使用したいことがあります - それはない場合、それは文字を使用して分割されますがデリミタとして$IFSにあります。これは変数をエコーし​​ているだけでは気付かれませんが、ファイルにコピーしたいファイル名のリストが含まれている場合は、変数が引用符で囲まれていない場合は$IFSで区切られます。欲しい、または期待している。

あなたが(むしろ読ん使うよりも変数にロード)マイク・クラークのアプローチを使用したい場合は、catを使用せずにそれを行うことができます。

NAMES="$(< scripts/names.txt)" #names from names.txt file 
for NAME in $NAMES; do 
    echo "$NAME" 
done 

これに伴う問題は、それが全体をロードすることですファイルを$NAMESに書き込むと、それを読み返すときに、ファイル全体(引用されている場合)またはファイルを$IFS(引用符で囲まれていない場合)にすることができます。デフォルトでは、個々の単語ではなく個々の単語が表示されます。したがって、 "Mary Jane"という名前が並んでいれば、 "Mary"と "Jane"は別々の名前になります。あなたも$IFS

2

これはあなたのために働くかもしれない:オリジナルのQ&Aへのリンクについて

cat <<\! >names.txt 
> alison 
> barb 
> charlie 
> david 
> ! 
OIFS=$IFS; IFS=$'\n'; NAMES=($(<names.txt)); IFS=$OIFS 
echo "${NAMES[@]}" 
alison barb charlie david 
echo "${NAMES[0]}" 
alison 
for NAME in "${NAMES[@]}";do echo $NAME;done 
alison 
barb 
charlie 
david 
関連する問題