29

名前のリストを含むファイルが 1 つあります。シェルスクリプトを使用して、外部ファイルからこのファイル内のすべての名前をループする必要があります。どうやってやるの?

サンプル ファイル:

スクリプト/names.txt

alison
barb
charlie
david

スクリプト/script.sh

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

names.txt ファイルを別のシェル スクリプトで配列に分解するにはどうすればよいですか?

4

5 に答える 5

60

1つの方法は次のとおりです。

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

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

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

于 2012-07-05T17:59:43.330 に答える
15

「読み取り」コマンドを使用する必要があります

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

「$name」は引用符で囲まれていることに注意してください。引用符で囲まれていない場合、$IFS区切り文字として文字を使用して分割されます。これは、変数をエコーするだけではおそらく気付かないでしょうが、コピーしたいファイル名のリストがファイルに含まれている$IFS場合、変数が引用符で囲まれていない場合、それらは分解されます。これはあなたが望むものではありませんまたは期待します。

マイク・クラークのアプローチ (読み取りを使用するのではなく、変数にロードする) を使用する場合は、を使用せずに実行できますcat

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

これに関する問題は、ファイル全体を にロードすること$NAMESです。それを読み戻すと、ファイル全体 (引用されている場合) または引用されて$IFSいない場合は によって分割されたファイルを取得できます。デフォルトでは、個々の行ではなく、個々の単語が表示されます。そのため、「Mary Jane」という名前が 1 行に表示された場合、「Mary」と「Jane」が 2 つの別々の名前として表示されます。を使用readすると、これを回避できます...ただし、の値を変更することもできます$IFS

于 2012-07-05T17:59:10.750 に答える
8
cat names.txt|while read line; do
    echo "$line";
done
于 2012-07-05T17:58:46.140 に答える
5

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

NAMES=`cat scripts/names.txt` #names from names.txt file
for NAME in $NAMES; do
   echo "$NAME"
done
于 2012-07-05T17:58:27.293 に答える
2

これはあなたのために働くかもしれません:

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
于 2012-07-05T19:19:07.413 に答える