SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

業務でラクするためのUNIXテクニック集

業務で楽するためのUNIXテクニック集
まずはおさらい、シェル制御構造と正規表現の基礎

第0回


理解しておくと便利なシェルの制御構造

 bashは単純なコマンドだけではなく制御文も受けつけます。制御構造を使うと定型的な処理を行うのが楽になります。

コマンドの繰り返し

 シェルで繰り返しを行うにはfor文、while文、until文などがあります。ここでは、コマンドライン上でよく利用されるfor文、while文を紹介します。

for文

 for文ではリストから項目を1つずつ取り出します。取り出した値は、指定した一時変数に格納され、処理内容が実行されます。処理内容はdodoneの間に記述します。

for 変数 in リスト
do
   繰り返し実行される処理内容
done

 コマンドライン上では次のように使用します。

$ for i in 1 2 3 4 5  [改行]
> do                  [改行]
> echo "$i"           [改行]
> done                [改行]
1
2
3
4
5

 上記の「>」は2次プロンプトと呼ばれるもので、コマンドがまだ完結していないときにシェルが表示します。また、次のように1行で書くこともできます。

$ for i in 1 2 3 4 5; do echo "$i"; done
※注2

 csh・tcshでは、複数行の構造を1行にまとめることはできません。また、bash 3以降では、数字の範囲を次のように指定することも可能です。

$ for i in {1..5}; do echo "$i"; done

 なお for文では、次のように条件の設定を指定することもできます。

for((i=0; i<5; i++)); do echo "$i"; done

 算術式は必ず二重括弧(())を使ってください。

 さらに、dodoneは中括弧("{""}")で置き換えることができるため、次のようにC言語のような形式で指定することも可能です。

for((i=1; i<5; i++)){ echo "$i"; }

 次の例ではfor文を利用して、すべてのファイル名に拡張子「.bak」を付けています。

$ for file in *; { mv -i "$file" "$file.bak"; }

 なお、スペースなどを含むファイル名を正しく処理させるために、変数は「""」で囲むようにしてください。

while文

 while文は繰返し処理の制御を行います。構文は次のようにwhileに続けて条件を記述します。処理内容はdodoneの間に記述します。

while 条件
do
   繰り返し実行されるコマンド
done

 次の例は、すべてのファイル中の行数を表示します。while文を利用すると次のように記述できます。

$ ls *  ← 全ファイル・ディレクトリを一覧表示
sec1.txt        sec2.txt        sec3.txt

$ find ./ -type f | while read file; do wc -l "$file"; done
       3 ./sec1.txt
       4 ./sec2.txt
       5 ./sec3.txt

 findコマンドの出力結果を、while readfileという変数に取り込みます。

※注3

 古いバージョンのfindコマンドを利用している方は、「-print」オプションを追加しないと正しく動作しません。

条件分岐

 シェルの条件分岐にはcase文とif文があります。ここではif文を取り上げます

if文

 if文は、コマンドの終了コードに基づき、行わせる処理が異なる場合に使用します。

 構文は次のように、コマンド1の実行結果が成立(終了コードが0の場合)なら「コマンド1が成立した時に実行するコマンド」を実行します。「elif コマンド2...」は省略することも複数記述することもできます。「else ...」は省略可能です。

if コマンド1
then
    コマンド1が成立(終了コードが0の場合)した時に実行するコマンド
[elif コマンド2
 then
    コマンド1が不成立で、コマンド2が成立した時に実行するコマンド]
[else
   コマンド1、コマンド2が不成立の時に実行するコマンド]
fi

 次の例ではif文を利用して、ディレクトリの中に存在するディレクトリとファイルの数を表示しています。

$ ls *   ← 全ファイル・ディレクトリを一覧表示
sec1.txt

dir:
dir2/            sec1.txt        sec2.txt        sec3.txt

$ for dir in *; { if [ -d "$dir" ] ; then echo "$dir:"; ls "$dir" | wc -l; fi; }
dir:
       4

 「-d "$dir"」の-dオプションは、引数$dirがディレクトリであるかどうかを調べます。ディレクトリの場合は成功します(0を返します)。リストを利用して、次のようにも記述できます。

$ for dir in *; { [ -d "$dir" ] && (echo "$dir:"; ls "$dir" | wc -l); }

理解しておくと便利な正規表現

 UNIXで使われる正規表現には、基本正規表現と拡張正規表現の2種類があります。

 sedgrepexprはデフォルトでは基本正規表現を使用します。またperlやruby、emacsなどは、それぞれ独自に拡張した正規表現を使用しているので注意が必要です。

基本正規表現の表記一覧
記号 意味
[] 括弧内の任意の1文字にマッチします。
[^ ] 括弧内以外の文字にマッチします。
¥(パターン¥) 正規表現パターンをひとまとめのグループとして扱います。
* 直前の正規表現の0回以上の繰り返しを行います。
¥{n,m¥} 直前の正規表現のn回以上、m回以下の繰り返しを行います。
¥{n¥} 直前の正規表現のn回の繰り返しを行います。
¥{n,¥} 直前の正規表現のn回以上の繰り返しを行います。
^ 文字列の先頭、あるいは行の先頭にマッチします。
$ 文字列の最後、あるいは行の最後にマッチします。
¥ 正規表現に使われる記号を普通の文字として扱います。
. 任意の1文字にマッチします。

 ファイル名から拡張子を取り除いて表示するコマンドは、sedコマンドを利用して次のように記述できます。

$ ls
test1.bak  test2.c  test3.html  test4.txt

$ ls * | sed 's/¥.[^.]*$//'
test1
test2
test3
test4

 「sed 's/\.[^.]*$//'」とすれば最後のピリオド以降行末までが削除されます。また、入力がピリオドを含まない(拡張子を持たない)場合は、何も行いません。このコマンドであれば、拡張子が不定の場合でも使用可能です。

まとめ

 今回は、覚えておくべきシェルの制御構造、正規表現に関して簡単に説明しました。

 次回からは、これらのコマンドや制御構造を組み合わせて、業務で楽できるようなテクニックをテーマ別に紹介します。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
業務でラクするためのUNIXテクニック集連載記事一覧

もっと読む

この記事の著者

保田和隆(ヤスダカズタカ)

Yasuda Kazutakaネットワーク関連の組み込みソフトウェア開発者。http://uguisu.skr.jp/Windows/

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3014 2008/10/23 08:24

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー