コピペ可|bash/while read lineで行単位で処理:5パターン
こんにちは。
普段はIT業界についてのブログを執筆してるエンジニアです。
» 参考:プログラマーの年収は200万円以下です【IT業界の残酷な成功法則】
» 参考:【一生使える本です】bashの解説書 厳選3選【おすすめ】
今回は、bashについての解説記事です。
bashのwhile read lineについて調べる人
「bashでwhile read lineを使うと1行ずつ入力を読み込めて便利だったと思うのですが、書き方を忘れました。正しい書き方はどのようにすればいいでしょう?コピペで利用可能な例が見たいです。」
こんな疑問を解決します。
本記事の内容
この記事を書いている私はIT業界歴12年、年収1,000万円ちょっとの金融系エンジニアです。IRIXやSolarisなどのUnixやCygwin、mac、Linuxなど様々な環境でbashによるスクリプティングを行ってきました。
bashは極めて簡単なプログラミング言語ですが、空白の有無などで構文エラーとなること、javaなど一般的なプログラミング言語に慣れている方にとっては直感的ではない構文であることから、忘れてしまうことも多いかと思います。そのため、bashのwhile read lineについて記事にしました。
本記事では、細かい構文に迷ったら、例からコピー&ペーストして使えることを目指しました。少しでもお役に立てますと幸いです。
データを行単位で処理する方法は2種類
LinuxなどUNIX系の環境でデータを行単位で処理したいなら、主にやり方は2つあります。
[データを行単位で処理する方法]
- その1:AWKを使ってデータを行単位に読み込んで処理する
- その2:シェルスクリプトのwhile read line句を使う
<本記事の内容>
その1:AWKを使う方法
AWKは行単位にテキストデータを処理するためのプログラミング言語(スクリプト言語)です。
データを加工したり区切ったり、少々複雑なテキスト処理をする場合はシェルで処理するよりもAWKにデータを渡して処理した方が便利です。
AWKで/etc/passwdからログイン不可のユーザ(/usr/bin/false)を抽出して加工して表示するプログラム例
cat /etc/passwd |\ awk -F: '$7=="\/usr\/bin\/false"{print $1 " - " $5}'
その2:while read line句を使う方法
こちらが本記事のテーマです。
以下では、AWKを使わずに純粋なシェルスクリプトだけでテキストデータに対し行単位に処理を行っていく方法を解説します。
bashにおけるwhile read lineの使い方
- 何を行単位で処理する?
1.外部のファイル
2.シェル内に定義したデータ
3.コマンド実行した結果出力
1.”外部のファイル”を行単位で処理
while read lineのうちline
は変数名です。
line
でなくどんな変数名にしてもOKです。
構文
[構文1]
do
《コマンド》
done < 《ファイル名》
具体例
例:os.txtから一行ずつ読み込んだ文字列を出力する
while read line do echo "read line:$line" done < ./os.txt
以下のように、一行ずつ読み込む対象のテキストを別途用意します。
windows mac linux
実行結果は以下の通りです。
read line:windows read line:mac read line:linux
2."シェル内に定義したデータ"を行単位で処理
while read lineを使う場合、以下の構文を用いると外部ファイルを読み込まずに使うことができます。
構文
[構文2]
do
《コマンド》
done < 《キーワード》
《データ》
《キーワード》
《キーワード》はEOF
やEND
など何でもOKでして、読み込むテキストの開始と終了を判定するものです。
具体例
例:一行ずつ読み込んだ文字列を出力する
while read line do echo "read line:$line" done < EOF windows mac linux EOF
この場合でも、実行結果は同じです。
read line:windows read line:mac read line:linux
別の書き方
個人的にEOF
やEND
が好きではありません。その場合、以下のようにも記述できます。
[構文3]
do
《コマンド》
done
シングルクォートは、《データ》を改行するために必須です。テキストが次の行に続いているよ、というのを表現しています。
具体例
例:echoで一行ずつ読み込んだ文字列を出力する
echo 'windows mac linux' | while read line do echo "read line:$line" done
この場合でも、実行結果は同じです。
read line:windows read line:mac read line:linux
3."コマンド実行した結果出力"を行単位で処理
上のechoの例と同じ構文を使えば、echo以外のコマンド実行結果を1行ずつ処理することができます。
構文
[構文4]
do
《コマンド2》
done
具体例
cat os.txt | while read line do echo "read line:$line" done
read line:windows read line:mac read line:linux
コマンド結果を使うので、より複雑なコマンドを実行した結果を1行ずつ処理するのに便利です。
次の例では、小文字を大文字に変換してから1行ずつ処理を実行します。
cat os.txt | tr 'a-z' 'A-Z' | while read line do echo "read line:$line" done
read line:WINDOWS read line:MAC read line:LINUX
行をさらにカラム(単語)に分けて処理する
最初のAWKのプログラムと同じように、行単位かつ単語単位でデータを区切って(コロン:区切り)処理してみます。
なお、/etc/passwdはこんな感じのコロン区切りのデータです。
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false root:*:0:0:System Administrator:/var/root:/bin/sh daemon:*:1:1:System Services:/var/root:/usr/bin/false _cvs:*:72:72:CVS Server:/var/empty:/usr/bin/false
AWKとbash/while read lineでの行単位処理を比べる
最初に解説した、/etc/passwdからログイン不可のユーザ(/usr/bin/false)を抽出して加工して表示する例を、①AWKで書いた場合、②bashのwhile read lineで書いた場合それぞれのコード例を示します。
①AWKで処理する場合
cat /etc/passwd |\ awk -F: '$7=="\/usr\/bin\/false"{print $1 " - " $5}'
②bashで処理する場合
cat /etc/passwd | while IFS=: read \ user d uid gid detail home shell do [ "$shell" = "/usr/bin/false" ] && echo "$user - $detail" done
for文でwhile read lineを代替する方法
物覚えの悪い私は、あまりwhile read line
を使いません。多くの場合、for文で表現できるからです。
[構文5]
do
《コマンド》
done
具体例
例:for文での代替例
for x in `cat ./os.txt` do echo $x done
この場合でも、実行結果は同じです。
read line:windows read line:mac read line:linux
for文で代替できないケース
各行に空白を含む場合、for文ですと改行だけでなく空白でも区切られてしまうのでwhile read line
を使った方が便利です。
windows 10 mac OS X linux
for文を使うとこうなってしまいます。
read line:windows read line:10 read line:mac read line:OS read line:X read line:linux
つまり、for文では行単位ではなく単語単位で処理するということですね。
bashならこちらの書籍がオススメです
[改訂第3版]シェルスクリプト基本リファレンス #!/bin/shで、ここまでできる
定番の1冊『シェルスクリプト基本リファレンス』の改訂第3版。
シェルスクリプトの知識は、プログラマにとって長く役立つ知識です。本書では、複数のプラットフォームに対応できる移植性の高いシェルスクリプト作成に主眼を置き、基本から丁寧に解説。第3版では最新のLinux/FreeBSD/Solarisに加え、組み込み分野等で注目度の高いBusyBoxもサポート。合わせて、全収録スクリプトに関してWindowsおよびmacOS環境でのbashの動作確認も行い、さらなる移植性の高さを追求。ますますパワーアップした改訂版をお届けします。
Blog TOP シェルスクリプトを勉強したい人向け|bashの使い方 記事まとめ
bashの使い方 - もくじ
シェルとは
- シェルとは
- シェルはOSと会話するための言語
- シェルの種類(bash以外のシェル)
- シェルスクリプトとは
- シェルスクリプトの書き方条件式
- if else文
- 文字列の比較
- &&と||の使い方
- case文文字列操作
- 文字列の連結
- 文字列の一部を切り出す繰り返し
- for文
- while文
- while文でリストから1つ要素ずつ処理する定数
- 定数の定義
関数
- 関数の定義
デバッグ
実行権限
本