3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

find コマンドがめっちゃ便利だった話

Posted at

株式会社オズビジョンのユッコ (@terra_yucco) です。
今日は業務内で同僚のシェアしてくれた find コマンドが感動的だったのでついつい記事にしてしまいました。

find is so powerful!!

TL;DR

find [starting-point...] -newerXY reference 

Premise

vagrant@homestead:~$ find --version
find (GNU findutils) 4.7.0-git
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2)

今までは

find-newer があるのは知っており、これを使って「より新しいファイル」「より古いファイル」などを探すことはよくやっていました。
ただし皆様ご存知のように -newer は man にもあるように1、比較対象はあくまでファイルです。なので、このようにやっていました。

touch -t 201905051213.30 /tmp/baseline
find /path -type f -newer /tmp/baseline
rm -f /tmp/baseline

比較用の /tmp/baseline ファイルを時間指定で作成し、そのファイルとの比較で find -newer を使用し、終わってから削除するという流れです。

-newerXY があれば

find /path -type f -newermt "2019-05-05 12:13:30"

なんてシンプル!

-newerXYXY

せっかくなので、この神オプション (個人的) について man をベースに調べてみました。

-newerXY reference
Succeeds if timestamp X of the file being considered is newer than timestamp Y of the file reference.

X のタイムスタンプが参照したファイルの Y のタイムスタンプより新しいと考えられる場合に成功する。

The letters X and Y can be any of the following letters:

  • a The access time of the file reference
  • B The birth time of the file reference
  • c The inode status change time of reference
  • m The modification time of the file reference
  • t reference is interpreted directly as a time

XY に使えるのは以下の文字

letter 意味
a 参照されたファイルのアクセス時間
B 参照されたファイルの生成時間
c 参照先の i-node 状態が変化した時間
m 参照されたファイルの更新時間
t 参照先を直接時間として解釈する

Some combinations are invalid; for example, it is invalid for X to be t. Some combinations are not implemented on all systems;
for example B is not supported on all systems. If an invalid or unsupported combination of XY is specified, a fatal error results. Time specifications are interpreted as for the argument to the -d option of GNU date. If you try to use the birth time of a reference file, and the birth time cannot be determined, a fatal error message results. If you specify a test which refers to the birth time of files being examined, this test will fail for any files where the birth time is unknown.

組み合わせによっては不正になる。例えば Xt は指定できない。
組み合わせによっては特定のシステムで動かないことがある。例えば B は全てのシステムでサポートされているわけではない。
もし不正、もしくはサポートされていない XY の組み合わせが指定された場合、致命的なエラーが発生する。
時間を指定した場合は GNU date に -d で渡した引数と同じように解釈される。
もし生成時間を参照しようとして、それが定義されていない場合は、致命的エラーのメッセージが出力される。ファイルの生成時間を検証しようとした場合、生成時間が不明なファイルに対してはその検証は失敗する。

エンジニアとしては気になる不等号

-newer = より新しい なので、おそらく等しい場合は合致しないと予想しましたが、念のために検証しました。

まずファイル作成して

$ vagrant@homestead:~$ touch -t 201905051213.30 /tmp/baseline
vagrant@homestead:~$ stat /tmp/baseline
  File: /tmp/baseline
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 1449540     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/ vagrant)   Gid: ( 1000/ vagrant)
Access: 2019-05-05 12:13:30.000000000 +0000
Modify: 2019-05-05 12:13:30.000000000 +0000
Change: 2019-05-30 11:41:32.741698485 +0000
 Birth: -

同じ日時で検証。
合致しませんでした。

vagrant@homestead:~$ find /tmp/ -newermt "2019-05-05 12:13:30"
vagrant@homestead:~$

次に 1s 前を指定。
合致しました!

vagrant@homestead:~$ find /tmp/ -type f -newermt "2019-05-05 12:13:29"
/tmp/baseline
vagrant@homestead:~$ 

ちなみに、同じ日時を否定してあげると、きちんと合致しました。

vagrant@homestead:~$ find /tmp/ -type f ! -newermt "2019-05-05 12:13:30"
/tmp/baseline
vagrant@homestead:~$ 
vagrant@homestead:~$ find /tmp/ -type f -not -newermt "2019-05-05 12:13:30"
/tmp/baseline
vagrant@homestead:~$ 
  • [referred files] -newer [base][referred files] > [base]
  • [referred files] ! -newer [base][referred files] <= [base]

Birth の存在しないファイル

検証に touch で作成したファイルが stat で参照したら Birth: - となっていますので、せっかくなので man 記載の内容を試してみました。

vagrant@homestead:/tmp$ find /tmp/ -type f -newerBt "2019-05-05 12:13:30"
find: This system does not provide a way to find the birth time of a file.
find: invalid predicate `-newerBt'
vagrant@homestead:/tmp$ echo $?
1

こんな感じになりました。話のネタにしかなりませんが。
※ちなみにここで立ち上げているのは Homestead の Vagrant です。

Conclusion

今日のまとめとしては find コマンドめっちゃ便利という点です。
前にいた現場は HP-UX だったので、そもそも GNU の恩恵を受けられず、今の現場に来て最初に感動したのは date -d だったのも覚えています。

膨大なオプションのうち -newerXY しか紹介できなかったので、折に触れて他もまた触れ、使いこなしていきたいと思います。

  1. -newer file: File was modified more recently than file. If file is a symbolic link and the -H option or the -L option is in effect, the modification time of the file it points to is always used.
    -newer file: ファイルが file より最近に変更されたかを示す。ファイルがシンボリックリンクで -H オプションもしくは -L オプションが効果的な場合は、リンク先のファイルの更新日時が参照される。

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?