複数ファイルの指定・ファイルの検索

16.6.6. 複数ファイルの指定・ファイルの検索

この節では複数ファイルの指定方法と、ファイルの検索の方法について説明します。

複数ファイルの指定 #

これまで説明してきたいろいろなファイル操作のコマンドは、複数のファイルをいっぺんに処理対象にすることができます。そのためには、ファイル名やディレクトリ名のところに以下のような特殊文字を使います。これらの特殊文字をワイルドカードといいます。

  • *(アスタリスク): 0 文字以上のあらゆる文字列
  • ?(疑問符) 任意の 1 文字
  • [文字列] [...] 内の文字の中のどれか 1 文字 例えば [abc]a, b, c のどれかという意味です。 また、[a-z] と書くと、a から z までのうちのどれか 1 文字、を意味します。
  • [!文字列] すぐ上の [文字列] と反対に、[ ] に含まれない 1 文字 [!a-y] は、aからy の範囲にない 1 文字(例えば、大文字、数字や小文字のz)を意味します。
  • {文字列 1, 文字列 2, ...}カンマで区切って並べられた文字列のどれか 1 つ

以下にいくつかの例を載せます(面倒なので、このページではディレクトリのことも単にファイルとよぶことにします)。

*       (名前が . で始まらないような)任意のファイル
.*      名前が . で始まる隠しファイル全て
*ro*    名前の中に ro を含むファイル全て
[a-s]*  名前の最初の文字が a から s であるファイル全て
g?b     1文字目が g、3文字目が b であるような3文字のファイルすべて
[A-Za]* 名前の最初の文字が大文字か a であるようなファイル全て
*.tex   拡張子が .tex であるファイル全て
*~      最後が ~ で終わるファイル全て

例外として、* だけ単独で指定しても、名前が . で始まる隠しファイルは対象になりません。 (設定で変更可能です)

ワイルドカードの展開 #

ワイルドカードの正確な意味は、「指定したパターンにマッチするファイル名の集合を持ってきて、その中身をパターンを書いた位置に展開する」ということです。

echo コマンドで、その展開の様子を確認することができます。次の入力と出力を例にとって説明します。

echo *.tex
bib.tex main.tex report.tex test.tex tmp.tex
  1. まず、入力の *.tex の部分がシェル( 16. シェルの活用 )によって展開され、入力したコマンドは次のように内部で書き換えられます。
    echo bib.tex main.tex report.tex test.tex tmp.tex
    
  2. その後、このコマンドが実際に実行されます。echo コマンドは単に後に続く文字列を出力するだけですから、結果として上に述べたようになるわけです。

ファイルの検索 #

コマンドライン上からファイルを検索するには、find コマンドや locate コマンドを使うのが便利です。find コマンドの方が高機能で、locate コマンドは(あらかじめ作られたファイル名のデータベースから検索するので)高速・簡便です。教育用計算機システムでは locate コマンドは設定されていないので、find コマンドのみ説明します。

find コマンドは、引数に検索対象のディレクトリと検索オプションを指定します。一番簡単な例は、.(カレントディレクトリ)以下のファイルを全部表示するものです。

find .
.
./base
./base/00readme.txt
./base/alltt.dtx
(後略)

この節の残りでは、検索対象のディレクトリの後に指定するオプションについて説明していきます。

検索条件の指定 #

-name オプションは、検索するファイル名を指定します。下の例では名前が 00readme.txt であるファイルや、alltt.* であるようなファイルを検索しています。

find base -name 00readme.txt
.base/00readme.txt
find base -name 'alltt.*'
base/alltt.dtx
base/alltt.ins

このように、条件にワイルドカードを指定する場合は " あるいは ' でくくる必要があります。そうでないと、先にシェルによって展開されてしまうからです。

通常のファイルやディレクトリ、あるいはシンボリックリンクのみ検索したいような場合には -type オプションを指定します。-type の後には次のどれかが指定できます。

f  通常のファイル
d  ディレクトリ
l  シンボリックリンク
b, c, p, s   スペシャルファイルやソケットなどの特殊なファイルです。ここでは説明しません。

例えば、次はディレクトリのみを検索します。

find . -type d
.
./base
./doc

ファイルの更新日時によって検索するには -mtime オプションを使います。対象とする範囲を次のような記法で指定します。

-mtime -45   45日前より後に更新されたファイル
-mtime +365 365日前より前に更新されたファイル
-mtime  0     0日前に更新されたファイル

なお、ここでいう「何日前」では、現在時刻との差の 24 時間未満の半端は切り上げられます。そのため

  • -mtime 0 は「この 24 時間内に更新されたファイル」
  • -mtime +0 は「24 時間より前に更新されたファイル」
  • -mtime -2 は「48 時間前より最近に更新されたファイル」

となります。似たようなものに -atime(最終アクセス日時)、-ctime(パーミッションなどステータスの変更日時)などのオプションがあり、-mtime と同じように使うことができますます。

他にも、所有者や所有しているグループ、ファイルサイズなども条件に加えることができます。

検索条件の演算 #

複数の検索条件を同時に指定して検索することもできます。例を挙げて説明します。

「名前が a から g で始まり末尾が .pdf で終わるファイル」と、「名前が a で始まるファイル」はそれぞれ以下で検索することができます。

find . -name '[a-g]*.pdf'
../classes.pdf
(後略)
find . -name 'a*'
.
./alltt.pdf
./alltt.log
(後略)

これらのオプションを続けて指定すると、両方の条件にマッチするファイルを検索することになります。2 つの条件を -a オプションでつなげても同じです。

find . -name '[a-g]*.pdf' -name 'a*'
../alltt.pdf

一方、両者を -o オプションで繋げると、少なくともどちらか片方にマッチするファイルを検索します。

find . -name '[a-g]*.pdf' -o -name 'a*'
.

また、条件を否定するには条件の前に ! をつけます。ただ実際にコマンドラインで入力するときには \! としないとエラーが起こる可能性があるので、注意してください。次の例では、名前が .ins で終わらないファイルを検索します。

find . \! -name '*.ins'
.
./ltsect.pdf
./ltfntcmd.pdf
(後略)
リンク 複数ファイルの指定・ファイルの検索 シェルの初期設定