本記事の構成および論理分析にはAI(人工知能)を使用しています。情報の正確性は、システム管理者(UNIXユーザー)による手動検証済みです。
第23回 テキストファイルを読みながら処理しよう:while readで1行ずつ処理する方法 | はじめてのシェルスクリプト

はじめてのシェルスクリプト | 第23回
はじめに
この連載では、macOS のターミナルで sh を使いながら、シェルスクリプトの基本を順番に学んでいきます。
前回(第22回)では、複数のコマンドを組み合わせた実用的なスクリプトを作りました。処理の流れをひとつのファイルにまとめることで、作業の自動化が現実的になってきましたね。
実際の業務では、「名前のリストが書かれたテキストファイルを1行ずつ読んで処理したい」「設定ファイルを読み込んで値を使いたい」という場面がよく出てきます。こうした処理を手動でこなすのは、行数が増えると現実的ではありません。
第23回では、while read を使ってテキストファイルを1行ずつ読みながら処理する方法を学びます。ループとファイル入力の組み合わせを理解すると、データ処理の自動化が大きく広がります。
この回で学ぶこと
while readの基本- テキストファイルを1行ずつ読む形
- 空白を含む行の扱い
- 入力ファイルを順番に処理する方法
IFS=と-rの基本- 入力元の考え方
- 行ごとの表示や整形の小さな実用例
テキストファイルを1行ずつ読むとは何か
1行ずつ順番に処理する
テキストファイルをまとめて扱うのではなく、1行ずつ順番に読み込んで処理したい場面があります。
そのときによく使うのが while read です。
基本の形
基本の形は次のとおりです。
while IFS= read -r line
do
echo "$line"
done < input.txt
この形では、input.txt の内容を1行ずつ line に入れて処理します。
サンプルコード
read_lines_sample.sh に次の内容を保存します。
#!/bin/sh
while IFS= read -r line
do
echo "読み込んだ行: $line"
done < names.txt
実行手順
1. 入力ファイルを作成する
まず、names.txt という名前で次の内容を保存します。
Taro
Hanako Suzuki
Ken
2. スクリプトを作成して保存する
エディタで read_lines_sample.sh という名前のファイルを作成し、次の内容を保存します。
#!/bin/sh
while IFS= read -r line
do
echo "読み込んだ行: $line"
done < names.txt
3. スクリプトを実行する
次のコマンドを実行します。
sh read_lines_sample.sh
実行結果の例です。
読み込んだ行: Taro
読み込んだ行: Hanako Suzuki
読み込んだ行: Ken
コードの読み方
while IFS= read -r line
1行読むたびに、その内容を line に入れています。
読み込める間は繰り返し処理が続きます。
IFS=
IFS は区切り文字に関する設定です。
ここで空にしておくと、行の先頭や末尾の空白が意図せず削られにくくなります。
read -r
-r を付けると、バックスラッシュを特別な文字として扱いにくくできます。
テキストをそのまま読みたいときは、この形を基本にしておくと扱いやすいです。
done < names.txt
names.txt を入力元として while に渡しています。
この部分があることで、標準入力ではなくファイルから読んでいることが分かります。
入力元の考え方
read は標準入力から読むこともできますが、今回のように done < names.txt と書くと、ファイルの内容を順番に読めます。
この違いが分からないと、「どこから入力されているのか」が見えにくくなります。
対話入力ではなくファイル処理をしたいときは、入力元をはっきり書くことが大切です。
空白を含む行を扱う
Hanako Suzuki のように空白を含む行でも、IFS= read -r line の形なら1行全体をそのまま扱いやすくなります。
単純な read line だけで始めることもできますが、空白や特殊文字を含む入力を考えるなら、今回の形を基準にした方が安全です。
初学者が混同しやすい点
ファイル名と1行の内容を混同する
names.txt は入力元のファイル名です。
line は、そのファイルから読み込んだ1行ごとの内容です。
while の最後で入力ファイルを指定する
done < names.txt はループ全体の入力元を指定しています。
これを見落とすと、どこから読み込んでいるかが分かりにくくなります。
IFS= と -r を省略する
省略しても動くことはありますが、空白やバックスラッシュを含む行では意図しない動作になりやすくなります。
よくあるエラー
no such file or directory
names.txt が同じディレクトリにあるか確認してください。
ファイル名の入力ミスでも同じエラーになります。
行が想定どおりに読めない
IFS= read -r の形になっているか確認してください。
特に空白を含む行を扱う場合は、この形が重要です。
対話入力待ちになってしまう
done < names.txt を書き忘れていないか確認してください。
入力元を指定しないと、標準入力から読もうとして待機することがあります。
練習用コード
次の内容で show_items.sh を作成して実行してみてください。
#!/bin/sh
while IFS= read -r item
do
echo "item: $item"
done < items.txt
items.txt を作成して、複数行の内容が順番に表示されることを確認してください。
この回で理解しておくこと
while readを使うとファイルを1行ずつ処理できるIFS= read -rの形は空白やバックスラッシュを扱いやすいdone < file.txtで入力元のファイルを指定できるlineのような変数には1行ずつ内容が入る- 標準入力から読む場合とファイルから読む場合は区別して考える
- 行単位の処理は小さな自動化でよく使う
まとめ
今回は、while IFS= read -r を使って、テキストファイルを1行ずつ読みながら処理する基本を確認しました。
この形を使えるようになると、設定ファイルや一覧ファイルを順番に処理するスクリプトを書きやすくなります。
次回は、総合演習としてバックアップ用スクリプトを作ります。
次回予告
次回は「総合演習:バックアップ用スクリプトを作ろう」です。
これまで学んだ基本を組み合わせて、小さな実用スクリプトを完成させます。









