シェルスクリプトで、ファイルに書かれた内容を 1 行ずつ処理したいケースってたまにありますよね。
いくつか方法はあるのですが、ファイルの容量や書きやすさなど好みに応じて使い分けてみるのが良さそうです。
今回は 3 パターンの方法を紹介したいと思います。
ファイルからの標準入力を読み込む
以下のように、1 行ごとにアルファベットが書かれたファイルを作成します。
1 2 3 4 5 6 7 | $ vi rilakkuma.txt A B C D E |
このアルファベットを 1 行ずつ画面に出力してみます。ファイルの内容を標準入力で while に受け渡します。
1 2 3 4 5 6 7 | $ vi run.sh #!/bin/sh while read line; do echo "alphabet: $line" done < rilakkuma.txt |
実行してみます。
1 2 3 4 5 6 | $ sh run.sh alphabet: A alphabet: B alphabet: C alphabet: D alphabet: E |
catした内容を標準入力として読み込む
ファイルの内容を cat で標準出力し、それを標準入力で while に受け渡します。
1 2 3 4 5 6 7 | $ vi run.sh #!/bin/sh cat rilakkuma.txt | while read line; do echo "alphabet: $line" done |
実行してみます。
1 2 3 4 5 6 7 | $ sh run.sh alphabet: A alphabet: B alphabet: C alphabet: D alphabet: E |
ファイルの内容を変数に格納して読み込む
ファイルの内容を変数に格納し、それを標準入力で while に受け渡します。
1 2 3 4 5 6 7 8 9 10 11 | $ vi run.sh #!/bin/sh rilakkuma=`cat abc.txt` while read line; do echo "alphabet: $line" done << EOL $rilakkuma EOL |
実行してみます。
1 2 3 4 5 6 7 | $ sh run.sh alphabet: A alphabet: B alphabet: C alphabet: D alphabet: E |
ちなみに、ロジック内の「EOL」はヒアドキュメントの開始と終了に使っている文字列で、特に「EOL」である必要はありません。
今回は End Of Line のつもりで EOL としています。SQL なら EOQ(End Of Query)とか。
完全に個人の好みですので、ヒアドキュメントを使う際は好きな文字列を使ってください。
ある程度、意味が通りそうな範囲でね。
まとめ
今回は、ファイルを読み込む方法を 3 つ紹介しましたが、特に指定がない限りはどれを使っても問題ありません。
プロジェクトなどで、他のソースと統一しておいた方がいいなっと思う場合は既存のソースにあわせておきましょう。
どれが正解というわけではないのですが、「標準入力のリダイレクト」「パイプ」「ヒアドキュメント」など、それぞれがどのようなものか理解しておくのもいいですね。
昔、上辺の知識でファイルディスクリプタについて勉強会で発表して、ボコボコに叩かれた嫌な記憶が思い起こされますが・・・orz
