web-dev-qa-db-ja.com

bashシェルスクリプトで、文字列値を反復するforループを記述する

Bashでは、ループ制御変数forが指定された整数を反復処理するiループを作成できることを知っています。たとえば、1〜10の整数を出力するbashシェルスクリプトを記述できます。

#!/bin/bash

for i in {1..10}
do
 echo $i
done

文字列のリストを提供する場合、代わりに文字列であるループ制御変数を反復処理することは可能ですか?たとえば、ファイル名を表す文字列fnameがあるとします。ファイル名ごとに一連のコマンドを呼び出します。たとえば、次のようなコマンドを使用してfnameの内容を出力したい場合があります。

#!/bin/bash

for fname in {"a.txt", "b.txt", "c.txt"}
do
 echo $fname
done

つまり、最初の反復では、fnameの値はfname="a.txt"、2回目の反復では、fnameの値はfname="b.txt"、 等々。残念ながら、上記の構文はまったく正しくないようです。出力を取得したい:

a.txt

b.txt

c.txt

しかし、上記のコードを試すと、次の出力が得られます。

{a.txt、

b.txt、

c.txt}

変数fnameの値/内容を繰り返し変更できるように、正しい構文を決定する手助けをしていただけませんか?お時間をいただきありがとうございます。

25
Andrew

正しい構文は次のとおりです。

#!/bin/bash

for fname in a.txt b.txt c.txt
do
  echo $fname
done
39
Ali Gangji

あなたはただやるべきだと私には思える...

printf %s.txt\\n a b c
1
mikeserv

comments のuser13742で述べられているように、bashおよびkshで配列を使用できます。

#!/usr/bin/env bash

files_list=( "a.txt" "b.txt" "c and space.txt" )

for i in "${files_list[@]}"
do
    echo "$i"
    # do something else here,maybe
done

そして、次のように機能します:

$ ./iterate_files_array.sh                                                      
a.txt
b.txt
c and space.txt

ただし、dash/bin/sh Ubuntuの場合)配列をサポートしていません。そのような場合、ヒアドキュメント構造を使用することに頼ることができます:<<

#!/bin/sh

while IFS= read -r line
do
    echo "$line"
done << EOL
one.txt
two.txt
with space.txt
EOL
0