ls、find、grep。
ファイル表示、ファイル検索に毎日使う基本的なコマンド達です。
毎日使ってはいても、これらのコマンドにはまだ自分が引き出せてない秘めた力がたくさんありそうだったので、一度腰を据えてmanページを読み込み、きちんと理解してみることにしました。
使用頻度が高いだけに、仲良くなればなるほど、日々の開発ライフ、運用ライフが豊かになるはず。
しっかり相手(コマンド)のことを理解し、最良の友となりましょう!
検証環境:Ubuntu 18.04.3 LTS on EC2
基本方針
- manページを全て読み、載っている全てのオプションを試す
- 調査した内容を基にコマンドの基本的な使用方法とオプションの全体像をまとめる
- 使用頻度が高そうなオプションは、実行例を含めて詳細を説明する
- それ以外でたまに使いそうなオプションは、概要を説明する
- オプションの使用頻度の判断は基本的に主観だが、自分の周りの人がよく使っていそうなものは漏らさないようにする
コマンド解説① lsコマンド
$ whatis ls
ls (1) - list directory contents
ディレクトリのファイルリストを表示するコマンド。
Linuxを使い始める人がまず最初に覚え、使用頻度も一番高いであろう愛すべきコマンド。
検証バージョンはこちら。
$ ls --version
ls (GNU coreutils) 8.28
基本的な使い方
いまさら説明するまでもありませんが、念のため。
# カレントディレクトリのファイルリストを表示
$ ls
hoge piyo
# 指定したディレクトリのファイルリストを表示
$ ls /var/
backups cache crash lib local lock log mail opt run snap spool tmp
# 詳細情報を表示
$ ls -l
total 8
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:26 hoge
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:28 piyo
# ドットファイルを含めて表示
$ ls -a
. .. .bash_history .bashrc hoge piyo
全体を俯瞰してみる
lsコマンドで指定できるオプションは、大きく3種類。
- 表示対象指定
- 表示方法(表示フォーマット)指定
- 表示順指定
なのでコマンドを使う際には、下記の順で考えて使用するオプションを決めるのがよさそう。
** どのディレクトリやファイルを表示対象としたいのか**
** ↓**
** 表示対象としたファイルについて、どのような情報を表示したいのか**
** ↓**
** 情報を表示する際に、リストをどの順序で表示したいのか**
ちなみに指定できるオプション数は全部で59個あります。
心が折れそうな数ですが、最良の友となるために全部試していきましょう。
カテゴリ | オプション数 | 備考 |
---|---|---|
表示対象指定 | 9 | |
表示方法指定 | 37 | |
表示順指定 | 11 | |
その他 | 2 | --helpと--version |
表示対象指定
まずは表示対象の指定から。
主に下記のようなことを指定可能。
- 表示対象とするディレクトリやファイル
- ドットファイルを表示するか
- リンクはリンク自体の情報を表示するか、それともリンク先の情報を表示するか
- サブディレクトリの中身も表示するか
# 表示対象とするディレクトリやファイルは引数で指定する(複数指定可能)
$ ls /usr/ /var/
/usr/:
bin games include lib local sbin share src
/var/:
backups cache crash lib local lock log mail opt run snap spool tmp
# -a ドットファイルを含めて表示する(.と..も含む)
$ ls -a
. .. .bash_history .bashrc hoge piyo
# -A ドットファイルを含めて表示する(.と..は含まない)
$ ls -A
.bash_history .bashrc hoge piyo
# -d ディレクトリの中身ではなく、ディレクトリ自体の情報を表示
$ ls -ld /usr/
drwxr-xr-x 10 root root 4096 Oct 2 17:08 /usr/
# -H リンク先の情報を表示する
## 説明のためにまずリンクを作成
$ ln -s /usr
## -Hを指定しない場合
$ ls -l usr
lrwxrwxrwx 1 ubuntu ubuntu 5 Dec 15 13:37 usr -> /usr
## リンク自体の情報を表示する
## -Hを指定した場合
$ ls -lH usr
total 48
drwxr-xr-x 2 root root 20480 Dec 14 13:41 bin
drwxr-xr-x 2 root root 4096 Apr 24 2018 games
drwxr-xr-x 4 root root 4096 Dec 14 13:40 include
・・・
## リンク先の情報を表示(ls -l usr/ でも可)
# -R サブディレクトリの中身も含めて表示する
$ ls -R /var/lib/dpkg
/var/lib/dpkg:
alternatives cmethopt diversions-old lock parts status triggers
available diversions info lock-frontend statoverride status-old updates
/var/lib/dpkg/alternatives:
awk ex infobrowser jsonpointer lzma newt-palette pinentry rmt rvim traceroute6 vim w
builtins.7.gz from jsondiff jsonschema mt pager rcp rsh telnet vi vimdiff write
editor ftp jsonpatch locate nc pico rlogin rview text.plymouth view vtrgb
/var/lib/dpkg/info:
・・・
# -I GLOB 指定したファイル名に一致するファイルを非表示にする(ワイルドカードを使用可能)
## -Iを指定しない場合
$ ls /usr/
bin games include lib local sbin share src
## -Iを指定した場合
$ ls -I *bin /usr/
games include lib local share src
## binとsbinが非表示になった
表示対象指定関連の全オプション
-a, --all
do not ignore entries starting with .
-A, --almost-all
do not list implied . and ..
-B, --ignore-backups
do not list implied entries ending with ~
-d, --directory
list directories themselves, not their contents
-H, --dereference-command-line
follow symbolic links listed on the command line
--hide=PATTERN
do not list implied entries matching shell PATTERN (overridden by -a or -A)
-I, --ignore=PATTERN
do not list implied entries matching shell PATTERN
-L, --dereference
when showing file information for a symbolic link, show information for the file the link references rather than for the
link itself
-R, --recursive
list subdirectories recursively
-B
バックアップファイルを表示しない、-L
コマンドラインで指定したディレクトリ以外もリンク先の情報を表示する、なども指定可能。また-I
に似たオプションとして--hide
があるが、-a
、-A
と同時指定できないので-I
のほうがおすすめ。
実用的には
-A ドットファイルを含めて表示する(.と..は含まない)
-R サブディレクトリの中身も含めて表示する
-I GLOB 指定したファイル名に一致するファイルを非表示にする
あたりを覚えておけばよさそう。
表示方法指定
lsコマンドの主要オプション群。
表示対象としたファイルを多彩なフォーマットで表示可能。
主に下記のようなことを指定可能。
- ファイルの種類を表示するか
- ファイルリストはカラムで表示するか、1ファイル1行で表示するか
- ファイルの詳細情報を表示するか
- 詳細情報表示時に表示する情報
- 詳細情報表示時のファイルサイズや日付のフォーマット
# -F ファイルの種類を記号で表示する
$ ls -F /lib/
apparmor/ ebtables/ klibc-wBFLvVtxy4xJqEadIBJMa78iJz8.so* lsb/ modules-load.d/ recovery-mode/ udev/
console-setup/ hdparm/ libhandle.so.1@ modprobe.d/ netplan/ systemd/ ufw/
cryptsetup/ init/ libhandle.so.1.0.3 modules/ open-iscsi/ terminfo/ x86_64-linux-gnu/
## / ディレクトリ
## * 実行可能ファイル
## @ リンク
# -1 1ファイル1行で表示する
$ ls -1 /usr/
bin
games
include
lib
local
sbin
share
src
# -m ファイルリストをカンマ区切りで表示する
$ ls -m /usr/
bin, games, include, lib, local, sbin, share, src
# -C リダイレクトやパイプ時もカラムで表示する(通常の画面表示時と同様の表示)
## -Cを指定しない場合
$ ls > test.txt
$ cat test.txt
hoge
piyo
test.txt
## リダイレクトすると1ファイル1行となる
## -Cを指定した場合
$ ls -C > test.txt
$ cat test.txt
hoge piyo test.txt
## リダイレクトしてもカラム表示のままとなる
# -i ファイルのinodeを表示する
$ ls -i
268594 hoge 283029 piyo 256221 test.txt 256220 usr
# -l 詳細情報を表示する(ロングフォーマット表示)
$ ls -l
total 12
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:26 hoge
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:28 piyo
-rw-rw-r-- 1 ubuntu ubuntu 23 Dec 16 14:50 test.txt
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 16 14:14 usr -> /usr
## ファイルリストの最初の一文字はd:ディレクトリ、l:リンク、-:ファイル
## その後はパーミッション、ハードリンク数、所有者、グループ、ファイルサイズ、更新日時、ファイル名が表示される
## 一番最初の行に表示されている「total 12」はブロックサイズの合計(サブディレクトリは含まない)
# -s ファイル毎のブロックサイズを表示する
$ ls -s
total 12
4 hoge 4 piyo 4 test.txt 0 usr
## 検証した環境だと1ブロック=1024バイトで表示された
# -g 所有者を表示しない(-lの指定がなくてもロングフォーマット表示になる)
# -o グループを表示しない(-lの指定がなくてもロングフォーマット表示になる)
$ ls -go
total 12
drwxrwxr-x 2 4096 Dec 14 14:26 hoge
drwxrwxr-x 2 4096 Dec 14 14:28 piyo
-rw-rw-r-- 1 23 Dec 16 15:03 test.txt
lrwxrwxrwx 1 4 Dec 16 14:14 usr -> /usr
# -h ファイルサイズを読みやすい単位で表示する(-lの指定が必要)
$ ls -lh /lib/
total 172K
drwxr-xr-x 2 root root 4.0K Oct 2 17:10 apparmor
drwxr-xr-x 2 root root 4.0K Oct 2 17:09 console-setup
drwxr-xr-x 4 root root 4.0K Oct 2 17:10 cryptsetup
drwxr-xr-x 2 root root 4.0K Oct 2 17:10 ebtables
drwxr-xr-x 2 root root 4.0K Oct 2 17:10 hdparm
drwxr-xr-x 2 root root 4.0K Oct 2 17:09 init
-rwxr-xr-x 1 root root 73K Nov 9 2017 klibc-wBFLvVtxy4xJqEadIBJMa78iJz8.so
lrwxrwxrwx 1 root root 18 Apr 18 2018 libhandle.so.1 -> libhandle.so.1.0.3
-rw-r--r-- 1 root root 15K Apr 18 2018 libhandle.so.1.0.3
・・・
# --full-time 更新日時をナノ秒まで表示し、タイムゾーンも表示する(-lの指定は不要)
$ ls --full-time
total 12
drwxrwxr-x 2 ubuntu ubuntu 4096 2019-12-14 14:26:20.908303620 +0000 hoge
drwxrwxr-x 2 ubuntu ubuntu 4096 2019-12-14 14:28:04.972521167 +0000 piyo
-rw-rw-r-- 1 ubuntu ubuntu 23 2019-12-16 15:03:09.700972620 +0000 test.txt
lrwxrwxrwx 1 ubuntu ubuntu 4 2019-12-16 14:14:22.280880698 +0000 usr -> /usr
表示方法指定関連の全オプション
--author
with -l, print the author of each file
-b, --escape
print C-style escapes for nongraphic characters
--block-size=SIZE
scale sizes by SIZE before printing them; e.g., '--block-size=M' prints sizes in units of 1,048,576 bytes; see SIZE format
below
-C list entries by columns
--color[=WHEN]
colorize the output; WHEN can be 'always' (default if omitted), 'auto', or 'never'; more info below
-D, --dired
generate output designed for Emacs' dired mode
-F, --classify
append indicator (one of */=>@|) to entries
--file-type
likewise, except do not append '*'
--format=WORD
across -x, commas -m, horizontal -x, long -l, single-column -1, verbose -l, vertical -C
--full-time
like -l --time-style=full-iso
-g like -l, but do not list owner
-G, --no-group
in a long listing, don't print group names
-h, --human-readable
with -l and/or -s, print human readable sizes (e.g., 1K 234M 2G)
--si likewise, but use powers of 1000 not 1024
--dereference-command-line-symlink-to-dir
follow each command line symbolic link
that points to a directory
--hide=PATTERN
do not list implied entries matching shell PATTERN (overridden by -a or -A)
--hyperlink[=WHEN]
hyperlink file names; WHEN can be 'always' (default if omitted), 'auto', or 'never'
--indicator-style=WORD
append indicator with style WORD to entry names: none (default), slash (-p), file-type (--file-type), classify (-F)
-i, --inode
print the index number of each file
-I, --ignore=PATTERN
do not list implied entries matching shell PATTERN
-k, --kibibytes
default to 1024-byte blocks for disk usage
-l use a long listing format
-m fill width with a comma separated list of entries
-n, --numeric-uid-gid
like -l, but list numeric user and group IDs
-N, --literal
print entry names without quoting
-o like -l, but do not list group information
-p, --indicator-style=slash
append / indicator to directories
-q, --hide-control-chars
print ? instead of nongraphic characters
--show-control-chars
show nongraphic characters as-is (the default, unless program is 'ls' and output is a terminal)
-Q, --quote-name
enclose entry names in double quotes
--quoting-style=WORD
use quoting style WORD for entry names: literal, locale, shell, shell-always, shell-escape, shell-escape-always, c, escape
-s, --size
print the allocated size of each file, in blocks
--time=WORD
with -l, show time as WORD instead of default modification time: atime or access or use (-u); ctime or status (-c); also
use specified time as sort key if --sort=time (newest first)
--time-style=STYLE
with -l, show times using style STYLE: full-iso, long-iso, iso, locale, or +FORMAT; FORMAT is interpreted like in 'date';
if FORMAT is FORMAT1<newline>FORMAT2, then FORMAT1 applies to non-recent files and FORMAT2 to recent files; if STYLE is
prefixed with 'posix-', STYLE takes effect only outside the POSIX locale
-T, --tabsize=COLS
assume tab stops at each COLS instead of 8
-w, --width=COLS
set output width to COLS. 0 means no limit
-x list entries by lines instead of by columns
-Z, --context
print any security context of each file
-1 list one file per line. Avoid '\n' with -q or -b
-b
制御文字をエスケープして表示する、-q
制御文字を?で表示する、-Q
ファイル名をダブルクォートで括って表示する、-n
所有者とグループをIDで表示する、なども指定可能。
その他、ファイルサイズや時間表示のさらに細かいフォーマットの指定や、タブサイズや表示幅の指定といったオプションもあるが、使用頻度はあまり高くなさそう。
おすすめのオプションは
-F ファイルの種類を記号で表示する
-h ファイルサイズを読みやすい単位で表示する(-lの指定が必要)
--full-time 更新日時をナノ秒まで表示し、タイムゾーンも表示する
あたり。
表示順指定
lsコマンドの仕上げ。
ファイルリストの表示順を指定する。
主に下記のようなことをが可能。
- 更新日時などのタイムスタンプで並び替え
- ファイルサイズで並び替え
- ファイルの種類(拡張子)で並び替え
- 数字を辞書順ではなく自然な数字順で並び替え
# -t ファイルリストを更新日時の降順(最新ファイルが一番上)で並び替え
$ ls -lt
total 12
-rw-rw-r-- 1 ubuntu ubuntu 23 Dec 16 15:03 test.txt
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 16 14:14 usr -> /usr
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:28 piyo
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:26 hoge
# -r ファイルリストの並び順を逆にする
$ ls -ltr
total 12
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:26 hoge
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:28 piyo
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 16 14:14 usr -> /usr
-rw-rw-r-- 1 ubuntu ubuntu 23 Dec 16 15:03 test.txt
# -c ファイルリストをステータス更新日時(ctime)の降順で並び替え(-ltとの同時指定時)
$ ls -ltc
total 12
-rw-rw-r-- 1 ubuntu ubuntu 23 Dec 16 15:03 test.txt
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 16 14:14 usr -> /usr
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:28 piyo
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:26 hoge
## リストに表示される時間もステータス更新日時になる
## -lcの指定だと、時間表示はステータス更新日時で名前順に表示
## -cのみの指定だと、ステータス更新日時順でファイル名のリストのみ表示
# -u ファイルリストをファイルアクセス日時(atime)の降順で並び替え(-ltとの同時指定時)
$ ls -ltu
total 12
-rw-rw-r-- 1 ubuntu ubuntu 23 Dec 19 14:48 test.txt
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 19 14:32 usr -> /usr
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:28 piyo
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 14 14:26 hoge
## リストに表示される時間もファイルアクセス日時になる
## -luの指定だと、時間表示はファイルアクセス日時で名前順に表示
## -uのみの指定だと、ファイルアクセス日時順でファイル名のリストのみ表示
# -S ファイルリストをファイルサイズの降順で並び替え
$ ls -lS /bin/
total 15320
-rwxr-xr-x 1 root root 2062296 Mar 6 2019 busybox
-rwxr-xr-x 1 root root 1113504 Jun 6 2019 bash
-rwxr-xr-x 1 root root 716464 Mar 12 2018 btrfs
-rwxr-xr-x 1 root root 584072 Sep 5 03:59 udevadm
-rwxr-xr-x 1 root root 554104 Feb 26 2018 ip
-rwxr-xr-x 1 root root 423312 Jan 21 2019 tar
・・・
# -X ファイルの拡張子で並び替え
## -Xを指定しない場合
$ ls -l
total 0
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 hoge.a
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 hoge.b
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 hoge.c
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 piyo.a
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 piyo.b
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 piyo.c
## -Xを指定した場合
$ ls -lX
total 0
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 hoge.a
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 piyo.a
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 hoge.b
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 piyo.b
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 hoge.c
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 19 15:30 piyo.c
# -v 自然な数字順で並び替え
## -vを指定しない場合(10、100が2の前に来る)
$ ls
1.so 10.so 100.so 2.so 20.so 200.so 3.so 30.so 300.so
## -vを指定した場合(数字順に並ぶ)
$ ls -v
1.so 2.so 3.so 10.so 20.so 30.so 100.so 200.so 300.so
表示順指定関連の全オプション
-c with -lt: sort by, and show, ctime (time of last modification of file status information); with -l: show ctime and sort by
name; otherwise: sort by ctime, newest first
-f do not sort, enable -aU, disable -ls --color
--group-directories-first
group directories before files;
can be augmented with a --sort option, but any use of --sort=none (-U) disables grouping
-r, --reverse
reverse order while sorting
-S sort by file size, largest first
-t sort by modification time, newest first
-u with -lt: sort by, and show, access time; with -l: show access time and sort by name; otherwise: sort by access time, new‐
est first
-U do not sort; list entries in directory order
-v natural sort of (version) numbers within text
-X sort alphabetically by entry extension
--sort=WORD
sort by WORD instead of name: none (-U), size (-S), time (-t), version (-v), extension (-X)
-f
-U
並び替えを行わない、--group-directories-first
ディレクトリを先に表示、なども指定可能。
よく使うオプションは
-t ファイルリストを更新日時の降順(最新ファイルが一番上)で並び替え
-S ファイルリストをファイルサイズの降順で並び替え
-r ファイルリストの並び順を逆にする
あたり。
おまけ
ls以外でファイル情報を表示するコマンドとして、stat
とfile
がある。
stat
はファイルのシステム関連の情報、file
はファイル形式の情報を表示できる。
さらに詳細情報を見たい場合に活用しましょう。
$ stat /bin/ls
File: /bin/ls
Size: 133792 Blocks: 264 IO Block: 4096 regular file
Device: ca01h/51713d Inode: 27 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2019-12-19 06:25:04.969727807 +0000
Modify: 2018-01-18 09:43:49.000000000 +0000
Change: 2019-10-02 17:11:13.386742626 +0000
Birth: -
$ file /bin/ls
/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=9567f9a28e66f4d7ec4baf31cfbf68d0410f0ae6, stripped
コマンド解説② findコマンド
$ whatis find
find (1) - search for files in a directory hierarchy
ディレクトリ階層からファイル名などでファイルを検索するコマンド。
検証バージョンはこちら。
$ find --version
find (GNU findutils) 4.7.0-git
基本的な使い方
# 指定したパス配下から、指定したファイル名に一致するファイルを検索
## ファイル名にはワイルドカードを指定可能
## -printはファイル名を表示するというアクションの指定(省略可能)
## 下記は、/usr/bin/配下のディレクトリからファイル名の先頭がaptのファイルを検索してファイル名を表示する例
$ find /usr/bin/ -name 'apt*' -print
/usr/bin/apt
/usr/bin/apt-get
/usr/bin/apt-key
/usr/bin/apt-mark
/usr/bin/apt-extracttemplates
/usr/bin/apt-sortpkgs
/usr/bin/apt-ftparchive
/usr/bin/apt-config
/usr/bin/apt-add-repository
/usr/bin/apt-cache
/usr/bin/apt-cdrom
# パスを省略するとカレントディレクトリを検索
$ find -name 'hoge' -print
./hoge
# 見つけたファイルに対して、コマンド実行をすることも可能
$ find -name 'hoge' -exec file '{}' \;
./hoge: directory
findコマンドを使う際にシェル展開がされないようにする必要があるため、制御文字を'apt*'、'{}'のようにシングルクォートで括ったり、;のようにエスケープをする必要がある。
全体を俯瞰してみる
findコマンドの使用方法で肝となるのが、引数の指定順と式の理解。
$ find [オプション] [検索するパス...] [式]
$ find -P /usr/bin/ -name 'apt*' -print
コマンドの後にオプションが来るのはlsコマンドなどの一般的なコマンドと一緒だが、オプションの位置に指定できるものは限られており、あまり頻繁には使わないものが多い。よく使う-name
などは式なので、これらの検索条件は検索するパスの後ろに指定する。
そのためfindコマンドは、下記のようにfind
のすぐ後にパスを指定し、その後にオプションのようなものを指定する形式になることが多い。
$ find /usr/bin/ -name 'apt*' -print
一見すると一般的なコマンドとはオプション類の指定順が逆のように見えるが、パスを指定してから式を記載するという書式にまず慣れるのがfindに親しむコツ。
式に指定可能なものは下記に分けられる。
カテゴリ | 説明 | オプション数 |
---|---|---|
位置オプション | 指定した箇所から後ろの式に影響があるオプション 警告メッセージの表示有無などを指定する |
4 |
グローバルオプション | どこに指定しても全体に影響があるオプション 指定されたパスの何階層目までを検索するかなどを指定する |
11 |
演算子 | ANDやORなど、条件の論理演算方法を指定する | 7 |
検査 | 検索条件などを指定する | 45 |
アクション | コマンドなどを実行する | 17 |
式の中でも、どんな条件でファイルを検索するかという「検査」と、検索条件に合致したファイルに対して何をするかという「アクション」がfindコマンドのメイン。
findコマンドを使う際には下記の順で考えてコマンドを組み立てるのがよさそう。
** 検索の前提条件(リンク先まで検索するか、警告メッセージを表示するか、何階層目まで検索するかなど)を決め、**
** 「検索するパスの前に指定できるオプション」、「位置オプション」、「グローバルオプション」として指定する**
** ↓**
** 検索するファイル名やファイルタイプなどの検索条件を決め、**
** 「検査」として指定する。ORやANDなどが含まれる条件は「演算子」を使用して表現する**
** ↓**
** 検索条件に合致したファイルに対して何をしたいかを決め、**
** 「アクション」として指定する**
lsコマンドもオプションが多いと感じたが、findコマンドはさらに指定できるオプションが多く、何よりmanページのボリュームがヤバイ。
$ man ls | wc -c
7760
$ man find | wc -c
72785
ちなみに複雑なコマンドとしてまず頭に浮かぶawkコマンドのmanページは下記の通り。
$ man awk | wc -c
90017
awkといい勝負をするとは、やるなfind。
かなり骨がありそうですが、仲良くなればかなり心強い味方になってくれるはず。
さあ張り切って進めていきましょう。
オプション
検索するパスの前に指定できるオプション。全部で5種類。
主に下記のようなことを指定可能。
- リンク先も検索するか
- デバッグ情報を表示するか
- 使用する最適化ロジック
# -P リンク先は検索しない(デフォルトの動作)
$ ls -l usr
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 16 14:14 usr -> /usr
$ find -P usr -name 'usr'
usr
## リンク先は検索せず、リンク自体の情報を表示する
# -H コマンドラインに指定されたものはリンク先を検索する
$ ls -l usr
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 16 14:14 usr -> /usr
$ find -H usr -name 'usr'
usr
usr/src/linux-headers-4.15.0-1051-aws/usr
usr/src/linux-headers-4.15.0-1056-aws/usr
usr/src/linux-aws-headers-4.15.0-1056/usr
usr/src/linux-aws-headers-4.15.0-1051/usr
usr/share/gdb/auto-load/usr
# -L サブディレクトリにあるものも含めて全てのリンク先を検索する
$ ls -l usr
lrwxrwxrwx 1 ubuntu ubuntu 4 Dec 16 14:14 usr -> /usr
$ find -L usr -name 'usr'
usr
usr/src/linux-headers-4.15.0-1051-aws/usr
usr/src/linux-headers-4.15.0-1056-aws/usr
usr/src/linux-aws-headers-4.15.0-1056/usr
usr/src/linux-aws-headers-4.15.0-1051/usr
usr/share/gdb/auto-load/usr
find: ‘usr/lib/ssl/private’: Permission denied
find: File system loop detected; ‘usr/bin/X11’ is part of the same file system loop as ‘usr/bin’.
## 検索先が非常に多くなる可能性があるので注意
## また、リンクがループしてエラーが出ることがある
manページ記載の全オプション
OPTIONS
The -H, -L and -P options control the treatment of symbolic links. Command-line arguments following these are taken to be names
of files or directories to be examined, up to the first argument that begins with `-', or the argument `(' or `!'. That argument
and any following arguments are taken to be the expression describing what is to be searched for. If no paths are given, the cur‐
rent directory is used. If no expression is given, the expression -print is used (but you should probably consider using -print0
instead, anyway).
This manual page talks about `options' within the expression list. These options control the behaviour of find but are specified
immediately after the last path name. The five `real' options -H, -L, -P, -D and -O must appear before the first path name, if at
all. A double dash -- can also be used to signal that any remaining arguments are not options (though ensuring that all start
points begin with either `./' or `/' is generally safer if you use wildcards in the list of start points).
-P Never follow symbolic links. This is the default behaviour. When find examines or prints information a file, and the file
is a symbolic link, the information used shall be taken from the properties of the symbolic link itself.
-L Follow symbolic links. When find examines or prints information about files, the information used shall be taken from the
properties of the file to which the link points, not from the link itself (unless it is a broken symbolic link or find is
unable to examine the file to which the link points). Use of this option implies -noleaf. If you later use the -P option,
-noleaf will still be in effect. If -L is in effect and find discovers a symbolic link to a subdirectory during its
search, the subdirectory pointed to by the symbolic link will be searched.
When the -L option is in effect, the -type predicate will always match against the type of the file that a symbolic link
points to rather than the link itself (unless the symbolic link is broken). Actions that can cause symbolic links to
become broken while find is executing (for example -delete) can give rise to confusing behaviour. Using -L causes the
-lname and -ilname predicates always to return false.
-H Do not follow symbolic links, except while processing the command line arguments. When find examines or prints information
about files, the information used shall be taken from the properties of the symbolic link itself. The only exception to
this behaviour is when a file specified on the command line is a symbolic link, and the link can be resolved. For that
situation, the information used is taken from whatever the link points to (that is, the link is followed). The information
about the link itself is used as a fallback if the file pointed to by the symbolic link cannot be examined. If -H is in
effect and one of the paths specified on the command line is a symbolic link to a directory, the contents of that directory
will be examined (though of course -maxdepth 0 would prevent this).
If more than one of -H, -L and -P is specified, each overrides the others; the last one appearing on the command line takes
effect. Since it is the default, the -P option should be considered to be in effect unless either -H or -L is specified.
GNU find frequently stats files during the processing of the command line itself, before any searching has begun. These options
also affect how those arguments are processed. Specifically, there are a number of tests that compare files listed on the command
line against a file we are currently considering. In each case, the file specified on the command line will have been examined
and some of its properties will have been saved. If the named file is in fact a symbolic link, and the -P option is in effect (or
if neither -H nor -L were specified), the information used for the comparison will be taken from the properties of the symbolic
link. Otherwise, it will be taken from the properties of the file the link points to. If find cannot follow the link (for exam‐
ple because it has insufficient privileges or the link points to a nonexistent file) the properties of the link itself will be
used.
When the -H or -L options are in effect, any symbolic links listed as the argument of -newer will be dereferenced, and the time‐
stamp will be taken from the file to which the symbolic link points. The same consideration applies to -newerXY, -anewer and
-cnewer.
The -follow option has a similar effect to -L, though it takes effect at the point where it appears (that is, if -L is not used
but -follow is, any symbolic links appearing after -follow on the command line will be dereferenced, and those before it will
not).
-D debugopts
Print diagnostic information; this can be helpful to diagnose problems with why find is not doing what you want. The list
of debug options should be comma separated. Compatibility of the debug options is not guaranteed between releases of find‐
utils. For a complete list of valid debug options, see the output of find -D help. Valid debug options include
exec Show diagnostic information relating to -exec, -execdir, -ok and -okdir
help Explain the debugging options.
opt Prints diagnostic information relating to the optimisation of the expression tree; see the -O option.
rates Prints a summary indicating how often each predicate succeeded or failed.
search Navigate the directory tree verbosely.
stat Print messages as files are examined with the stat and lstat system calls. The find program tries to minimise such
calls.
tree Show the expression tree in its original and optimised form.
-Olevel
Enables query optimisation. The find program reorders tests to speed up execution while preserving the overall effect;
that is, predicates with side effects are not reordered relative to each other. The optimisations performed at each opti‐
misation level are as follows.
0 Equivalent to optimisation level 1.
1 This is the default optimisation level and corresponds to the traditional behaviour. Expressions are reordered so
that tests based only on the names of files (for example -name and -regex) are performed first.
2 Any -type or -xtype tests are performed after any tests based only on the names of files, but before any tests that
require information from the inode. On many modern versions of Unix, file types are returned by readdir() and so
these predicates are faster to evaluate than predicates which need to stat the file first. If you use the -fstype
FOO predicate and specify a filesystem type FOO which is not known (that is, present in `/etc/mtab') at the time
find starts, that predicate is equivalent to -false.
3 At this optimisation level, the full cost-based query optimiser is enabled. The order of tests is modified so that
cheap (i.e. fast) tests are performed first and more expensive ones are performed later, if necessary. Within each
cost band, predicates are evaluated earlier or later according to whether they are likely to succeed or not. For
-o, predicates which are likely to succeed are evaluated earlier, and for -a, predicates which are likely to fail
are evaluated earlier.
The cost-based optimiser has a fixed idea of how likely any given test is to succeed. In some cases the probability takes
account of the specific nature of the test (for example, -type f is assumed to be more likely to succeed than -type c).
The cost-based optimiser is currently being evaluated. If it does not actually improve the performance of find, it will
be removed again. Conversely, optimisations that prove to be reliable, robust and effective may be enabled at lower opti‐
misation levels over time. However, the default behaviour (i.e. optimisation level 1) will not be changed in the 4.3.x
release series. The findutils test suite runs all the tests on find at each optimisation level and ensures that the result
is the same.
-D
デバッグ情報を表示する、-O
最適化ロジックを指定する、といったオプションもある。-D
は複雑な検索条件を指定していて判定ロジックの途中経過が見たい時、-O
はfindコマンド実行時に性能が出ない時に使うとよさそう。
位置オプション
指定した箇所から後ろの式に影響があるオプション。
主に下記のようなことを指定可能。
- 「検査」に時間を指定した場合の今日の始まりの考え方
(24時間前を今日の始まりとするか、0時を今日の始まりとするか) - コマンド実行時の警告メッセージを表示するか
- 使用する正規表現タイプ
# -daystart 今日の始まりをコマンド実行当日の0時にする
## 1月1日の12時に、今日更新されたファイルを検索した場合の例で説明
$ date
Wed Jan 1 12:00:00 UTC 2020
$ ls -l
total 8
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 31 21:00 hoge
drwxrwxr-x 2 ubuntu ubuntu 4096 Jan 1 9:00 piyo
## -daystartの指定なし
## 24時間以内に更新されたファイル(12月31日の12時〜1月1日の12時前までに更新されたファイル)を表示
$ find -mtime 0 -ls
268594 4 drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 31 21:00 ./hoge
283029 4 drwxrwxr-x 2 ubuntu ubuntu 4096 Jan 1 9:00 ./piyo
## -lsはファイルリストをロングフォーマットで表示するコマンド(詳細は「アクション」の項目参照)
## -daystartの指定あり
## コマンド実行当日の1月1日に更新されたファイル(1月1日の0時〜1月1日の24時前までに更新されたファイル)を表示
$ find -daystart -mtime 0
283029 4 drwxrwxr-x 2 ubuntu ubuntu 4096 Jan 1 9:00 ./piyo
# -nowarn 警告メッセージを表示しない
## -nowarn指定なしの場合
$ find -name 'hoge' -maxdepth 1
find: warning: you have specified the -maxdepth option after a non-option argument -name, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.
./hoge
## コマンド利用方法に関する警告メッセージが表示される
## 上記の例ではグローバルオプションである-maxdepthを式の最初に指定していないことで警告が出ている
## -nowarn指定ありの場合
$ find -nowarn -name 'hoge' -maxdepth 1
./hoge
## 警告メッセージは表示されない
## findコマンド使用時によく遭遇する「Permission denied」はエラー出力なので、-nowarnでは消せない
$ find /root/ -nowarn
/root/
find: ‘/root/’: Permission denied
## エラー出力を消したい時は、リダイレクトで捨てる
$ find /root/ 2> /dev/null
/root/
# -regextype 使用する正規表現タイプの指定
## findコマンドのデフォルトの正規表現はemacs
## emacs正規表現はエスケープが必要だったり使えない正規表現があったりするので、
## 拡張正規表現(posix-extended)の指定がおすすめ
$ find -regextype posix-extended -regex '.*(hoge|piyo){2}'
./piyopiyo
./hogehoge
manページ記載の全位置オプション
POSITIONAL OPTIONS
Positional options always return true. They affect only tests occurring later on the command line.
-daystart
Measure times (for -amin, -atime, -cmin, -ctime, -mmin, and -mtime) from the beginning of today rather than from 24 hours
ago. This option only affects tests which appear later on the command line.
-follow
Deprecated; use the -L option instead. Dereference symbolic links. Implies -noleaf. The -follow option affects only
those tests which appear after it on the command line. Unless the -H or -L option has been specified, the position of the
-follow option changes the behaviour of the -newer predicate; any files listed as the argument of -newer will be derefer‐
enced if they are symbolic links. The same consideration applies to -newerXY, -anewer and -cnewer. Similarly, the -type
predicate will always match against the type of the file that a symbolic link points to rather than the link itself. Using
-follow causes the -lname and -ilname predicates always to return false.
-regextype type
Changes the regular expression syntax understood by -regex and -iregex tests which occur later on the command line. To see
which regular expression types are known, use -regextype help. The Texinfo documentation (see SEE ALSO) explains the mean‐
ing of and differences between the various types of regular expression.
-warn, -nowarn
Turn warning messages on or off. These warnings apply only to the command line usage, not to any conditions that find
might encounter when it searches directories. The default behaviour corresponds to -warn if standard input is a tty, and
to -nowarn otherwise. If a warning message relating to command-line usage is produced, the exit status of find is not
affected. If the POSIXLY_CORRECT environment variable is set, and -warn is also used, it is not specified which, if any,
warnings will be active.
リンク先を検索する-follow
もあるが非推奨。代わりにオプションの-L
を使いましょう。
グローバルオプション
どこに指定しても全体に影響があるオプション。
主に下記のようなことを指定可能。
- ディレクトリ自体よりも先に、ディレクトリの中身を検索するか
- 指定されたパスの何階層目までを検索するか
- 指定されたパスから何階層目までを検索対象外とするか
# -depth ディレクトリ自体よりも先に、ディレクトリの中身を検索する
## 下記構成のディレクトリを検索
$ tree hoge
hoge
├── hoge.txt
└── piyo
└── piyo.txt
## -depthを指定しない場合
$ find hoge
hoge
hoge/piyo
hoge/piyo/piyo.txt
hoge/hoge.txt
## -depthを指定した場合
$ find hoge -depth
hoge/piyo/piyo.txt
hoge/piyo
hoge/hoge.txt
hoge
# -maxdepth 指定されたパスの何階層目までを検索するかを指定
# -mindepth 指定されたパスの何階層目までを検索対象外とするかを指定
## 下記構成のディレクトリを検索
$ tree hoge
hoge
├── hoge.txt
└── piyo
└── piyo.txt
## -maxdepth、-mindepthともに指定しない場合
$ find hoge
hoge
hoge/piyo
hoge/piyo/piyo.txt
hoge/hoge.txt
## -maxdepth 0 の場合は指定されたパスのみ
$ find hoge -maxdepth 0
hoge
## -maxdepth 1 の場合は1階層目までを検索
$ find hoge -maxdepth 1
hoge
hoge/piyo
hoge/hoge.txt
## -mindepth 2 の場合は2階層目以降を検索(1階層目までを検索対象外とする)
$ find hoge -mindepth 2
hoge/piyo/piyo.txt
## 同時指定も可能
$ find hoge -mindepth 1 -maxdepth 2
hoge/piyo
hoge/piyo/piyo.txt
hoge/hoge.txt
manページ記載の全グローバルオプション
GLOBAL OPTIONS
Global options always return true. Global options take effect even for tests which occur earlier on the command line. To prevent
confusion, global options should specified on the command-line after the list of start points, just before the first test, posi‐
tional option or action. If you specify a global option in some other place, find will issue a warning message explaining that
this can be confusing.
The global options occur after the list of start points, and so are not the same kind of option as -L, for example.
-d A synonym for -depth, for compatibility with FreeBSD, NetBSD, MacOS X and OpenBSD.
-depth Process each directory's contents before the directory itself. The -delete action also implies -depth.
-help, --help
Print a summary of the command-line usage of find and exit.
-ignore_readdir_race
Normally, find will emit an error message when it fails to stat a file. If you give this option and a file is deleted
between the time find reads the name of the file from the directory and the time it tries to stat the file, no error mes‐
sage will be issued. This also applies to files or directories whose names are given on the command line. This option
takes effect at the time the command line is read, which means that you cannot search one part of the filesystem with this
option on and part of it with this option off (if you need to do that, you will need to issue two find commands instead,
one with the option and one without it).
-maxdepth levels
Descend at most levels (a non-negative integer) levels of directories below the starting-points. -maxdepth 0
means only apply the tests and actions to the starting-points themselves.
-mindepth levels
Do not apply any tests or actions at levels less than levels (a non-negative integer). -mindepth 1 means process all files
except the starting-points.
-mount Don't descend directories on other filesystems. An alternate name for -xdev, for compatibility with some other versions of
find.
-noignore_readdir_race
Turns off the effect of -ignore_readdir_race.
-noleaf
Do not optimize by assuming that directories contain 2 fewer subdirectories than their hard link count. This option is
needed when searching filesystems that do not follow the Unix directory-link convention, such as CD-ROM or MS-DOS filesys‐
tems or AFS volume mount points. Each directory on a normal Unix filesystem has at least 2 hard links: its name and its
`.' entry. Additionally, its subdirectories (if any) each have a `..' entry linked to that directory. When find is exam‐
ining a directory, after it has statted 2 fewer subdirectories than the directory's link count, it knows that the rest of
the entries in the directory are non-directories (`leaf' files in the directory tree). If only the files' names need to be
examined, there is no need to stat them; this gives a significant increase in search speed.
-version, --version
Print the find version number and exit.
-xdev Don't descend directories on other filesystems.
下記のようなオプションもある。
-mount
別のファイルシステムにあるディレクトリを検索しない(-xdev
も同様)
-ignore_readdir_race
ファイル情報を取得できなかった場合にエラー表示をしない
-noleaf
.(カレントディレクトリ)と..(親ディレクトリ)がディレクトリに必ずある前提での最適化を行わない(CD-ROM、MS-DOSなどLinuxファイルシステム以外のディレクトリを検索する場合に使用)
-help
や-version
もグローバルオプション。
演算子
ANDやORなど、条件の論理演算方法を指定する。
下記のようなことが可能。
- ()での優先順位指定
- AND演算
- OR演算
- NOT演算
- カンマ演算(リスト)
# -and AND演算(-andは省略可能。-aでも可)
$ find -name '*hoge*' -and -name '*piyo*'
./hogepiyo
## 左辺がfalseの場合は右辺は評価しない
# -or OR演算(-oでも可)
$ find -name 'hoge' -or -name 'piyo'
./piyo
./hoge
## 左辺がtrueの場合は右辺は評価しない
# -not NOT演算(!でも可)
$ ls
hoge piyo
$ find -not -name 'hoge'
.
./piyo
# expr1 , expr2 カンマ演算(リスト)
## expr1とexpr2の両方を必ず評価する。リスト全体の値はexpr2の値となる
$ find -false -and -name 'hoge'
$ find -false , -name 'hoge'
./hoge
## -andの場合は左辺がfalseだと右辺の処理を行わないが、リストの場合は必ず右辺も評価される
## (-falseは常にfalseを返す式)
## カンマ演算は、アクションが途中で失敗しても以降の処理を継続させたい場合などに使用する
manページ記載の全演算子
OPERATORS
Listed in order of decreasing precedence:
( expr )
Force precedence. Since parentheses are special to the shell, you will normally need to quote them. Many of the examples
in this manual page use backslashes for this purpose: `\(...\)' instead of `(...)'.
! expr True if expr is false. This character will also usually need protection from interpretation by the shell.
-not expr
Same as ! expr, but not POSIX compliant.
expr1 expr2
Two expressions in a row are taken to be joined with an implied -a; expr2 is not evaluated if expr1 is false.
expr1 -a expr2
Same as expr1 expr2.
expr1 -and expr2
Same as expr1 expr2, but not POSIX compliant.
expr1 -o expr2
Or; expr2 is not evaluated if expr1 is true.
expr1 -or expr2
Same as expr1 -o expr2, but not POSIX compliant.
expr1 , expr2
List; both expr1 and expr2 are always evaluated. The value of expr1 is discarded; the value of the list is the value of
expr2. The comma operator can be useful for searching for several different types of thing, but traversing the filesystem
hierarchy only once. The -fprintf action can be used to list the various matched items into several different output
files.
Please note that -a when specified implicitly (for example by two tests appearing without an explicit operator between them) or
explicitly has higher precedence than -o. This means that find . -name afile -o -name bfile -print will never print afile.
検査
findコマンドの中心的存在。
どんな条件でファイルを検索するかを指定する。
主に下記のようなことが可能。
- ファイル名、パス名検索
- タイムスタンプ検索
- ファイルの属性(ファイルタイプ、パーミッション、サイズなど)検索
数が多いので、カテゴリ毎に見ていきましょう。
ファイル名、パス名検索
# -name pattern ファイル名を検索
$ find -name 'hoge'
./hoge
# -path pattern パスを検索
$ find /etc/ -path '*kernel*' 2> /dev/null
/etc/apt/apt.conf.d/01autoremove-kernels
/etc/apparmor.d/tunables/kernelvars
/etc/kernel
/etc/kernel/install.d
/etc/kernel/postinst.d
/etc/kernel/postinst.d/zz-update-grub
/etc/kernel/postinst.d/update-notifier
/etc/kernel/postinst.d/x-grub-legacy-ec2
/etc/kernel/postinst.d/apt-auto-removal
/etc/kernel/postinst.d/initramfs-tools
/etc/kernel/postinst.d/unattended-upgrades
/etc/kernel/postrm.d
/etc/kernel/postrm.d/zz-update-grub
/etc/kernel/postrm.d/x-grub-legacy-ec2
/etc/kernel/postrm.d/initramfs-tools
/etc/sysctl.d/10-kernel-hardening.conf
/etc/kernel-img.conf
# -lname pattern リンク先のパスを検索
$ find -lname '*local*' -ls
256325 0 lrwxrwxrwx 1 ubuntu ubuntu 14 Dec 24 15:04 ./bin -> /usr/local/bin
# -regex pattern 正規表現でパスを検索
## 拡張正規表現を使えるように、-regextype posix-extendedの同時指定がおすすめ
$ find /usr/ -regextype posix-extended -regex '.*[0-9]\.[0-9]{2}\.[0-9]-[0-9]{4}.*selinux'
/usr/src/linux-headers-4.15.0-1051-aws/scripts/selinux
/usr/src/linux-headers-4.15.0-1051-aws/include/config/security/selinux
/usr/src/linux-headers-4.15.0-1056-aws/scripts/selinux
/usr/src/linux-headers-4.15.0-1056-aws/include/config/security/selinux
/usr/src/linux-aws-headers-4.15.0-1056/scripts/selinux
/usr/src/linux-aws-headers-4.15.0-1056/security/selinux
/usr/src/linux-aws-headers-4.15.0-1051/scripts/selinux
/usr/src/linux-aws-headers-4.15.0-1051/security/selinux
大文字小文字を区別しない-iname
-ipath
-ilname
-iregex
もある。
タイムスタンプ検索
# -mmin n 更新日時がn分前のファイルを検索
# -mmin +n 更新日時がn分前より古いファイルを検索
# -mmin -n 更新日時がn分前より新しいファイルを検索
## 12時00分00秒にファイルを検索した場合の例で説明
$ date
Wed Jan 1 12:00:00 UTC 2020
$ touch -d '2020-1-1 11:57:00.000000001' 11:57:00.000000001.txt
$ touch -d '2020-1-1 11:58:00.000000001' 11:58:00.000000001.txt
$ touch -d '2020-1-1 11:59:00.000000001' 11:59:00.000000001.txt
## 境界値を含まないことを示すため、時間を1ナノ秒だけずらして設定
## 以降の説明では、「○:境界値を含まない」、「●:境界値を含む」の記号を用いる
## 更新日時が1分前未満〜現在(○11:59:00〜●12:00:00)のファイルを検索
$ find -mmin 1
./11:59:00.000000001.txt
## 更新日時が2分前未満〜1分前(○11:58:00〜●11:59:00)のファイルを検索
$ find -mmin 2
./11:58:00.000000001.txt
## 更新日時が3分前未満〜2分前(○11:57:00〜●11:58:00)のファイルを検索
$ find -mmin 3
./11:57:00.000000001.txt
## 更新日時が1分前より古いファイル(過去〜○11:59:00)を検索
$ find -mmin +1
./11:57:00.000000001.txt
./11:58:00.000000001.txt
## 更新日時が2分前より古いファイル(過去〜○11:58:00)を検索
$ find -mmin +2
./11:57:00.000000001.txt
## 更新日時が3分前より古いファイル(過去〜○11:57:00)を検索
$ find -mmin +3
### 該当なし
## 更新日時が1分前より新しいファイル(○11:59:00〜現在)を検索
$ find -mmin -1
./11:59:00.000000001.txt
## 更新日時が2分前より新しいファイル(○11:58:00〜現在)を検索
$ find -mmin -2
./11:58:00.000000001.txt
./11:59:00.000000001.txt
## 更新日時が3分前より新しいファイル(○11:57:00〜現在)を検索
$ find -mmin -3
./11:57:00.000000001.txt
./11:58:00.000000001.txt
./11:59:00.000000001.txt
# -mtime n 更新日時がn日前のファイルを検索
# -mtime +n 更新日時がn日前より古いファイルを検索
# -mtime -n 更新日時がn日前より新しいファイルを検索
## 1月1日の12時にファイルを検索した場合の例で説明
$ date
Wed Jan 1 12:00:00 UTC 2020
$ touch -d '2019-12-28 12:00:00.000000001' 2019-12-28_12:00:00.000000001.txt
$ touch -d '2019-12-29 12:00:00.000000001' 2019-12-29_12:00:00.000000001.txt
$ touch -d '2019-12-30 12:00:00.000000001' 2019-12-30_12:00:00.000000001.txt
$ touch -d '2019-12-31 12:00:00.000000001' 2019-12-31_12:00:00.000000001.txt
## 境界値を含まないことを示すため、時間を1ナノ秒だけずらして設定
## 位置オプションの-daystartは使用しない場合の例
## 更新日が1日前未満〜現在(○2019-12-31 12:00:00〜●2020-1-1 12:00:00)のファイルを検索
$ find -mtime 0
./2019-12-31_12:00:00.000000001.txt
## 更新日が2日前未満〜1日前(○2019-12-30 12:00:00〜●2019-12-31 12:00:00)のファイルを検索
$ find -mtime 1
./2019-12-30_12:00:00.000000001.txt
## 更新日が3日前未満〜2日前(○2019-12-29 12:00:00〜●2019-12-30 12:00:00)のファイルを検索
$ find -mtime 2
./2019-12-29_12:00:00.000000001.txt
## 更新日が4日前未満〜3日前(○2019-12-28 12:00:00〜●2019-12-29 12:00:00)のファイルを検索
$ find -mtime 3
./2019-12-28_12:00:00.000000001.txt
## 更新日時が1日前より古いファイル(過去〜●2019-12-31 12:00:00)を検索
$ find -mtime +0
./2019-12-28_12:00:00.000000001.txt
./2019-12-29_12:00:00.000000001.txt
./2019-12-30_12:00:00.000000001.txt
## 更新日時が2日前より古いファイル(過去〜●2019-12-30 12:00:00)を検索
$ find -mtime +1
./2019-12-28_12:00:00.000000001.txt
./2019-12-29_12:00:00.000000001.txt
## 更新日時が3日前より古いファイル(過去〜●2019-12-29 12:00:00)を検索
$ find -mtime +2
./2019-12-28_12:00:00.000000001.txt
## 更新日時が4日前より古いファイル(過去〜●2019-12-28 12:00:00)を検索
$ find -mtime +3
### 該当なし
## 更新日時が0日前より新しいファイル(○2020-1-1 12:00:00〜現在)を検索
$ find -mtime -0
### 常に現在と一致するため、どのファイルとも一致しない
## 更新日時が1日前より新しいファイル(○2019-12-31 12:00:00〜現在)を検索
$ find -mtime -1
./2019-12-31_12:00:00.000000001.txt
## 更新日時が2日前より新しいファイル(○2019-12-30 12:00:00〜現在)を検索
$ find -mtime -2
./2019-12-31_12:00:00.000000001.txt
./2019-12-30_12:00:00.000000001.txt
## 更新日時が3日前より新しいファイル(○2019-12-29 12:00:00〜現在)を検索
$ find -mtime -3
./2019-12-31_12:00:00.000000001.txt
./2019-12-30_12:00:00.000000001.txt
./2019-12-29_12:00:00.000000001.txt
## 実動作は上記の通りだが、mminとmtimeは0の扱いと+-指定時の境界の考え方が異なるためややこしい
## きちんと理解したい人は、後述の「mminとmtimeの仕様差異」を見てみてください
# -newer file 指定したファイルの更新日時より新しいファイルを検索
$ ls -l
total 0
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 21 12:00 2019-12-21.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 22 12:00 2019-12-22.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 23 12:00 2019-12-23.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 24 12:00 2019-12-24.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 25 12:00 2019-12-25.txt
$ find -newer 2019-12-23.txt
./2019-12-24.txt
./2019-12-25.txt
## ファイルのアクセス日時で検索する-amin、-atime、-anewer、
## ファイルのステータス更新日時で検索する-cmin、-ctime、-cnewerもある
# -newermt STRING 指定した日時よりも更新日時が新しいファイルを検索
$ find -newermt '2019-12-23'
./2019-12-23.txt
./2019-12-24.txt
./2019-12-25.txt
## 論理演算子と組み合わせて範囲を検索することも可能
$ find -newermt '2019-12-22' -not -newermt '2019-12-25'
./2019-12-22.txt
./2019-12-23.txt
./2019-12-24.txt
## ファイルのアクセス日時で検索する-newerat、
## ファイルのステータス更新日時で検索する-newerct、
## ファイルの作成日時で検索する-newerBtもある
## (ただし-newerBtはサポートされていないシステムもある)
下記のようなオプションもある。
-used n
ファイルのアクセス日時がステータス更新日時よりn日後のファイルを検索
mminとmtimeの仕様差異
mminとmtimeは、0の扱いと+-指定時の境界の考え方に仕様差異があるため、そこを理解して使用しないと混乱の元となる。
0の扱いの違い
mmin:0を使用せず、引数に指定する数字は1から始まる。0分〜1分未満を検索する場合は-mmin 1
mtime:0を使用し、引数に指定する数字は0から始まる。0日〜1日未満を検索する場合は-mtime 0
+-指定時の境界の考え方
mmin:+-指定時の境界値は点を指す。そのため、+の範囲と-の範囲は境界値の1点を除いて連続する範囲となる
-mmin +1
:過去〜○11:59:00
-mmin -1
:○11:59:00〜現在
どちらにも含まない範囲:●11:59:00
※ちなみに+-指定のないmmin 1
は「○11:59:00〜●12:00:00」を指すため、-mmin -1
の範囲と重複がある
mtime:+-指定時の境界値は範囲を指す。そのため、+の範囲と-の範囲は、連続する範囲とならない(24時間分を空けた範囲となる)
-mtime +1
:過去〜●2019-12-30 12:00:00
-mtime -1
:○2019-12-31 12:00:00〜現在
どちらにも含まない範囲:○2019-12-30 12:00:00〜●2019-12-31 12:00:00
※ちなみに+-指定のないmtime 1
は「○2019-12-30 12:00:00〜●2019-12-31 12:00:00」を指すため、-mtime +1
-mtime -1
mtime 1
の範囲を全てを合わせると、連続した範囲になる
どうして仕様を統一しないんだろう。。
理由を知っている人がいたら教えてください。
ファイルの属性(ファイルタイプ、パーミッション、サイズなど)検索
# ファイルタイプの検索
# -type f ファイルを検索
# -type d ディレクトリを検索
# -type l リンクを検索
$ ls -l
total 4
drwxrwxr-x 2 ubuntu ubuntu 4096 Dec 26 14:32 dir
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 26 14:32 file
lrwxrwxrwx 1 ubuntu ubuntu 1 Dec 26 14:33 link -> /
$ find -type f
./file
$ find -type d
.
./dir
$ find -type l
./link
# ファイルパーミッションの検索
## 下記のファイルに対してコマンドを実行した場合の例で説明
$ ls -l
total 0
-r-------- 1 ubuntu ubuntu 0 Dec 26 14:59 400.txt
-r--r----- 1 ubuntu ubuntu 0 Dec 26 14:58 440.txt
-rw------- 1 ubuntu ubuntu 0 Dec 26 14:57 600.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 26 14:56 664.txt
-rw-rw-rw- 1 ubuntu ubuntu 0 Dec 26 14:56 666.txt
-rwxrwxr-x 1 ubuntu ubuntu 0 Dec 26 14:58 775.txt
-rwxrwxrwx 1 ubuntu ubuntu 0 Dec 26 14:56 777.txt
# -readable 読み込み可能なファイルを検索
$ find -readable
.
./400.txt
./440.txt
./600.txt
./664.txt
./666.txt
./775.txt
./777.txt
# -writable 書き込み可能なファイルを検索
$ find -writable
.
./600.txt
./664.txt
./666.txt
./775.txt
./777.txt
# -executable 実行可能なファイルを検索
$ find -executable
.
./775.txt
./777.txt
# -perm XXX 引数に指定したパーミッションと完全に一致するファイルを検索
$ find -perm 664
./664.txt
# -perm -XXX 引数に指定したパーミッションが含まれるファイルを検索
$ find -perm -664
.
./664.txt
./666.txt
./775.txt
./777.txt
# -perm /XXX 引数に指定したパーミッションのいずれかが一致するファイルを検索
$ find -perm /444
.
./400.txt
./440.txt
./600.txt
./664.txt
./666.txt
./775.txt
./777.txt
# -size n サイズがnブロックのファイルを検索(1ブロックは512バイト)
# -size +n サイズがnブロックより大きいファイルを検索(1ブロックは512バイト)
# -size -n サイズがnブロックより小さいファイルを検索(1ブロックは512バイト)
## nに接尾辞をつけることでサイズの単位を指定できる
## c:バイト、k:キビバイト、M:メビバイト、G:ギビバイト
$ ls -l /var/log/syslog.*
-rw-r----- 1 syslog adm 18401 Dec 27 06:25 /var/log/syslog.1
-rw-r----- 1 syslog adm 1625 Dec 26 06:25 /var/log/syslog.2.gz
-rw-r----- 1 syslog adm 1618 Dec 25 06:25 /var/log/syslog.3.gz
-rw-r----- 1 syslog adm 2087 Dec 24 06:25 /var/log/syslog.4.gz
-rw-r----- 1 syslog adm 2048 Dec 23 06:25 /var/log/syslog.5.gz
-rw-r----- 1 syslog adm 1499 Dec 22 06:25 /var/log/syslog.6.gz
-rw-r----- 1 syslog adm 2453 Dec 21 06:25 /var/log/syslog.7.gz
## サイズが1,625バイトのファイルを検索
$ find /var/log/ -name 'syslog.*' -size 1625c -ls
7055 4 -rw-r----- 1 syslog adm 1625 Dec 26 06:25 /var/log/syslog.2.gz
## サイズが2,000バイトより大きいファイルを検索
$ find /var/log/ -name 'syslog.*' -size +2000c -ls
7012 4 -rw-r----- 1 syslog adm 2048 Dec 23 06:25 /var/log/syslog.5.gz
6306 24 -rw-r----- 1 syslog adm 18401 Dec 27 06:25 /var/log/syslog.1
7078 4 -rw-r----- 1 syslog adm 2453 Dec 21 06:25 /var/log/syslog.7.gz
7043 4 -rw-r----- 1 syslog adm 2087 Dec 24 06:25 /var/log/syslog.4.gz
## サイズが2キビバイトより大きいファイルを検索
$ find /var/log/ -name 'syslog.*' -size +2k -ls
6306 24 -rw-r----- 1 syslog adm 18401 Dec 27 06:25 /var/log/syslog.1
7078 4 -rw-r----- 1 syslog adm 2453 Dec 21 06:25 /var/log/syslog.7.gz
7043 4 -rw-r----- 1 syslog adm 2087 Dec 24 06:25 /var/log/syslog.4.gz
## サイズが2キビバイトのファイルを検索
$ find /var/log/ -name 'syslog.*' -size 2k -ls
7012 4 -rw-r----- 1 syslog adm 2048 Dec 23 06:25 /var/log/syslog.5.gz
7014 4 -rw-r----- 1 syslog adm 1499 Dec 22 06:25 /var/log/syslog.6.gz
7055 4 -rw-r----- 1 syslog adm 1625 Dec 26 06:25 /var/log/syslog.2.gz
7049 4 -rw-r----- 1 syslog adm 1618 Dec 25 06:25 /var/log/syslog.3.gz
### 単位を指定した場合は単位以下の数字が切り上げられるため、
### 1キビバイトを超えるサイズのファイルは2キビバイトとなる
## サイズが2キビバイト未満のファイルを検索
$ find /var/log/ -name 'syslog.*' -size -2k -ls
## 単位以下の数字が切り上げられるため、該当なしとなることに注意
# -empty 空のファイルもしくはディレクトリを検索
$ find /var/log -empty -ls
16133 0 -rw-r--r-- 1 root root 0 Dec 12 13:27 /var/log/landscape/sysinfo.log
7088 0 -rw-r----- 1 syslog adm 0 Dec 22 06:25 /var/log/kern.log
80414 4 drwxr-xr-x 2 root root 4096 Nov 23 2018 /var/log/lxd
80412 4 drwxr-xr-x 2 root root 4096 Jun 19 2019 /var/log/dist-upgrade
manページ記載の全検査
TESTS
Some tests, for example -newerXY and -samefile, allow comparison between the file currently being examined and some reference file
specified on the command line. When these tests are used, the interpretation of the reference file is determined by the options
-H, -L and -P and any previous -follow, but the reference file is only examined once, at the time the command line is parsed. If
the reference file cannot be examined (for example, the stat(2) system call fails for it), an error message is issued, and find
exits with a nonzero status.
Numeric arguments can be specified as
+n for greater than n,
-n for less than n,
n for exactly n.
-amin n
File was last accessed n minutes ago.
-anewer file
File was last accessed more recently than file was modified. If file is a symbolic link and the -H option or the -L option
is in effect, the access time of the file it points to is always used.
-atime n
File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any
fractional part is ignored, so to match -atime +1, a file has to have been accessed at least two days ago.
-cmin n
File's status was last changed n minutes ago.
-cnewer file
File's status was last changed more recently than file was modified. If file is a symbolic link and the -H option or the
-L option is in effect, the status-change time of the file it points to is always used.
-ctime n
File's status was last changed n*24 hours ago. See the comments for -atime to understand how rounding affects the inter‐
pretation of file status change times.
-empty File is empty and is either a regular file or a directory.
-executable
Matches files which are executable and directories which are searchable (in a file name resolution sense). This takes into
account access control lists and other permissions artefacts which the -perm test ignores. This test makes use of the
access(2) system call, and so can be fooled by NFS servers which do UID mapping (or root-squashing), since many systems
implement access(2) in the client's kernel and so cannot make use of the UID mapping information held on the server.
Because this test is based only on the result of the access(2) system call, there is no guarantee that a file for which
this test succeeds can actually be executed.
-false Always false.
-fstype type
File is on a filesystem of type type. The valid filesystem types vary among different versions of Unix; an incomplete list
of filesystem types that are accepted on some version of Unix or another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K. You
can use -printf with the %F directive to see the types of your filesystems.
-gid n File's numeric group ID is n.
-group gname
File belongs to group gname (numeric group ID allowed).
-ilname pattern
Like -lname, but the match is case insensitive. If the -L option or the -follow option is in effect, this test returns
false unless the symbolic link is broken.
-iname pattern
Like -name, but the match is case insensitive. For example, the patterns `fo*' and `F??' match the file names `Foo',
`FOO', `foo', `fOo', etc. The pattern `*foo*` will also match a file called '.foobar'.
-inum n
File has inode number n. It is normally easier to use the -samefile test instead.
-ipath pattern
Like -path. but the match is case insensitive.
-iregex pattern
Like -regex, but the match is case insensitive.
-iwholename pattern
See -ipath. This alternative is less portable than -ipath.
-links n
File has n hard links.
-lname pattern
File is a symbolic link whose contents match shell pattern pattern. The metacharacters do not treat `/' or `.' specially.
If the -L option or the -follow option is in effect, this test returns false unless the symbolic link is broken.
-mmin n
File's data was last modified n minutes ago.
-mtime n
File's data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the interpre‐
tation of file modification times.
-name pattern
Base of file name (the path with the leading directories removed) matches shell pattern pattern. Because the leading
directories are removed, the file names considered for a match with -name will never include a slash, so `-name a/b' will
never match anything (you probably need to use -path instead). A warning is issued if you try to do this, unless the envi‐
ronment variable POSIXLY_CORRECT is set. The metacharacters (`*', `?', and `[]') match a `.' at the start of the base name
(this is a change in findutils-4.2.2; see section STANDARDS CONFORMANCE below). To ignore a directory and the files under
it, use -prune; see an example in the description of -path. Braces are not recognised as being special, despite the fact
that some shells including Bash imbue braces with a special meaning in shell patterns. The filename matching is performed
with the use of the fnmatch(3) library function. Don't forget to enclose the pattern in quotes in order to protect it
from expansion by the shell.
-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.
-newerXY reference
Succeeds if timestamp X of the file being considered is newer than timestamp Y of the file reference. 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
Some combinations are invalid; for example, it is invalid for X to be t. Some combinations are not implemented on all sys‐
tems; 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.
-nogroup
No group corresponds to file's numeric group ID.
-nouser
No user corresponds to file's numeric user ID.
-path pattern
File name matches shell pattern pattern. The metacharacters do not treat `/' or `.' specially; so, for example,
find . -path "./sr*sc"
will print an entry for a directory called `./src/misc' (if one exists). To ignore a whole directory tree, use -prune
rather than checking every file in the tree. For example, to skip the directory `src/emacs' and all files and directories
under it, and print the names of the other files found, do something like this:
find . -path ./src/emacs -prune -o -print
Note that the pattern match test applies to the whole file name, starting from one of the start points named on the command
line. It would only make sense to use an absolute path name here if the relevant start point is also an absolute path.
This means that this command will never match anything:
find bar -path /foo/bar/myfile -print
Find compares the -path argument with the concatenation of a directory name and the base name of the file it's examining.
Since the concatenation will never end with a slash, -path arguments ending in a slash will match nothing (except perhaps a
start point specified on the command line). The predicate -path is also supported by HP-UX find and is part of the POSIX
2008 standard.
-perm mode
File's permission bits are exactly mode (octal or symbolic). Since an exact match is required, if you want to use this
form for symbolic modes, you may have to specify a rather complex mode string. For example `-perm g=w' will only match
files which have mode 0020 (that is, ones for which group write permission is the only permission set). It is more likely
that you will want to use the `/' or `-' forms, for example `-perm -g=w', which matches any file with group write permis‐
sion. See the EXAMPLES section for some illustrative examples.
-perm -mode
All of the permission bits mode are set for the file. Symbolic modes are accepted in this form, and this is usually the
way in which you would want to use them. You must specify `u', `g' or `o' if you use a symbolic mode. See the EXAMPLES
section for some illustrative examples.
-perm /mode
Any of the permission bits mode are set for the file. Symbolic modes are accepted in this form. You must specify `u', `g'
or `o' if you use a symbolic mode. See the EXAMPLES section for some illustrative examples. If no permission bits in mode
are set, this test matches any file (the idea here is to be consistent with the behaviour of -perm -000).
-perm +mode
This is no longer supported (and has been deprecated since 2005). Use -perm /mode instead.
-readable
Matches files which are readable. This takes into account access control lists and other permissions artefacts which the
-perm test ignores. This test makes use of the access(2) system call, and so can be fooled by NFS servers which do UID
mapping (or root-squashing), since many systems implement access(2) in the client's kernel and so cannot make use of the
UID mapping information held on the server.
-regex pattern
File name matches regular expression pattern. This is a match on the whole path, not a search. For example, to match a
file named `./fubar3', you can use the regular expression `.*bar.' or `.*b.*3', but not `f.*r3'. The regular expressions
understood by find are by default Emacs Regular Expressions, but this can be changed with the -regextype option.
-samefile name
File refers to the same inode as name. When -L is in effect, this can include symbolic links.
-size n[cwbkMG]
File uses n units of space, rounding up. The following suffixes can be used:
`b' for 512-byte blocks (this is the default if no suffix is used)
`c' for bytes
`w' for two-byte words
`k' for Kibibytes (KiB, units of 1024 bytes)
`M' for Mebibytes (MiB, units of 1024 * 1024 = 1048576 bytes)
`G' for Gibibytes (GiB, units of 1024 * 1024 * 1024 = 1073741824 bytes)
The size does not count indirect blocks, but it does count blocks in sparse files that are not actually allocated. Bear in
mind that the `%k' and `%b' format specifiers of -printf handle sparse files differently. The `b' suffix always denotes
512-byte blocks and never 1024-byte blocks, which is different to the behaviour of -ls.
The + and - prefixes signify greater than and less than, as usual; i.e., an exact size of n units does not match. Bear in
mind that the size is rounded up to the next unit. Therefore -size -1M is not equivalent to -size -1048576c. The former
only matches empty files, the latter matches files from 0 to 1,048,575 bytes.
-true Always true.
-type c
File is of type c:
b block (buffered) special
c character (unbuffered) special
d directory
p named pipe (FIFO)
f regular file
l symbolic link; this is never true if the -L option or the -follow option is in effect, unless the symbolic link is
broken. If you want to search for symbolic links when -L is in effect, use -xtype.
s socket
D door (Solaris)
To search for more than one type at once, you can supply the combined list of type letters separated by a comma `,' (GNU
extension).
-uid n File's numeric user ID is n.
-used n
File was last accessed n days after its status was last changed.
-user uname
File is owned by user uname (numeric user ID allowed).
-wholename pattern
See -path. This alternative is less portable than -path.
-writable
Matches files which are writable. This takes into account access control lists and other permissions artefacts which the
-perm test ignores. This test makes use of the access(2) system call, and so can be fooled by NFS servers which do UID
mapping (or root-squashing), since many systems implement access(2) in the client's kernel and so cannot make use of the
UID mapping information held on the server.
-xtype c
The same as -type unless the file is a symbolic link. For symbolic links: if the -H or -P option was specified, true if
the file is a link to a file of type c; if the -L option has been given, true if c is `l'. In other words, for symbolic
links, -xtype checks the type of the file that -type does not check.
-context pattern
(SELinux only) Security context of the file matches glob pattern.
下記のようなオプションもある。
-user
ファイルのユーザー名で検索(ユーザーID指定も可能)
-group
ファイルのグループ名で検索(グループID指定も可能)
-nouser
ファイルのユーザーIDに対応するユーザーがいないファイルを検索
-nogroup
ファイルのグループIDに対応するグループがいないファイルを検索
-context
SELinuxのセキュリティコンテキストを検索
アクション
findコマンドの仕上げ。
コマンドなどを実行するアクションの指定。
主に下記のようなことが可能。
- 任意のコマンドを1ファイルにつき1コマンドで実行
- 任意のコマンドを複数ファイルに対してまとめて実行
- ファイルリストをロングフォーマットや任意のフォーマットで表示
- ファイルを削除
任意のコマンド実行には-exec
を使う。
-exec
コマンドを実行するときは
$ find -type f -exec ls -l '{}' \;
のような感じで指定する。
{}にfindで見つかったファイルが展開される。
シェル展開されないように、{}や;はエスケープが必要。{}と;の間の空白は必須。
任意のコマンドを1ファイルにつき1コマンドで実行する場合は、最後に;を付ける。
任意のコマンドを複数ファイルに対してまとめて実行する場合は、最後に+を付ける。
-exec
で何でもできてしまうが、ファイルリスト表示やファイル削除などのよく使いそうなものは専用のコマンドが用意されている。
# -exec command ; 任意のコマンドを1ファイルにつき1コマンドで実行
# -exec command + 任意のコマンドを複数ファイルに対してまとめて実行
## ファイルのみを検索してlsコマンドを実行
$ find -type f -exec ls -l '{}' \;
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 27 15:06 ./piyo.txt
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 27 15:06 ./hoge.txt
## コマンドはfindを実行したディレクトリで実行される
## コマンドをファイルが存在するディレクトリで実行したい場合は-execdirを使う
## ;指定の場合は、1ファイルにつき1コマンドが実行される
$ find -type f -exec echo 'echoコマンド実行' '{}' \;
echoコマンド実行 ./piyo.txt
echoコマンド実行 ./hoge.txt
## +指定の場合は、(可能な限り)1回のコマンド実行にまとめられる
$ find -type f -exec echo 'echoコマンド実行' '{}' \+
echoコマンド実行 ./piyo.txt ./hoge.txt
## こっちのほうがパフォーマンスがいいので、通常は+での実行がおすすめ
# -ok ’-exec’コマンドとほぼ同じだが、コマンド実行前に確認メッセージを表示する
$ find -type f -ok ls -l '{}' \;
< ls ... ./piyo.txt > ? y
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 27 15:06 ./piyo.txt
< ls ... ./hoge.txt > ? y
-rw-rw-r-- 1 ubuntu ubuntu 0 Dec 27 15:06 ./hoge.txt
## コマンドをファイルが存在するディレクトリで実行したい場合は-okdirを使う
# -ls ファイルリストを表示する
$ find -type f -ls
256220 0 -rw-rw-r-- 1 ubuntu ubuntu 0 Dec 27 15:06 ./piyo.txt
256216 0 -rw-rw-r-- 1 ubuntu ubuntu 0 Dec 27 15:06 ./hoge.txt
## lsのロングフォーマットの情報に加えて、inodeとブロックサイズの情報を表示する
## -flsを代わりに使用することで、結果をファイルに格納することも可能
# -delete ファイルを削除
## 下記階層のディレクトリを例に説明
$ tree
.
├── hoge
│ └── hogehoge.txt
├── hoge.txt
├── piyo
│ └── piyopiyo.txt
└── piyo.txt
## -deleteは条件に合致するファイルを警告なしで全て消すので、
## 事前に-deleteなしで削除されるファイルを確認したほうがいい
$ find -depth -name 'hoge*'
./hoge/hogehoge.txt
./hoge
./hoge.txt
## -deleteはディレクトリの中身を消してからディレクトリ自体を削除する動作をするため、
## -depthオプションが暗黙的に指定される
## 削除されるファイルの順番も合わせて確認するために、
## 事前確認時も-depthオプションを付けるのがおすすめ
## ファイルの削除
$ find -depth -name 'hoge*' -delete
## メッセージは何も表示されない
## ファイルは削除されている
$ tree
.
├── piyo
│ └── piyopiyo.txt
└── piyo.txt
# -print ファイルリストを表示する(アクション省略時のデフォルト動作)
$ find -type f -print
./piyo.txt
./hoge.txt
# -print0 ファイルリストをnull文字(¥0)区切りで表示する
$ find -type f -print0
./piyo.txt./hoge.txt
## 空白や制御文字を含むファイル名があると、-printを使ってもうまくパイプで別コマンドに渡せない
## そのような場合に-print0を使用する
# -prune 指定したディレクトリ以下を検索対象外とする
## 下記階層のディレクトリを例に説明
$ tree
.
├── hoge
│ ├── hogehoge
│ │ └── hogehogehoge.txt
│ └── hogehoge.txt
└── piyo
├── piyopiyo
│ └── piyopiyopiyo.txt
└── piyopiyo.txt
## -pruneを指定しない場合
$ find -type f -print
./piyo/piyopiyo/piyopiyopiyo.txt
./piyo/piyopiyo.txt
./hoge/hogehoge.txt
./hoge/hogehoge/hogehogehoge.txt
## -pruneを指定した場合
$ find -name 'hoge' -prune -or -type f -print
./piyo/piyopiyo/piyopiyopiyo.txt
./piyo/piyopiyo.txt
### hogeディレクトリ配下を検索対象外にできる
manページ記載の全アクション
ACTIONS
-delete
Delete files; true if removal succeeded. If the removal failed, an error message is issued. If -delete fails, find's exit
status will be nonzero (when it eventually exits). Use of -delete automatically turns on the `-depth' option.
Warnings: Don't forget that the find command line is evaluated as an expression, so putting -delete first will make find
try to delete everything below the starting points you specified. When testing a find command line that you later intend
to use with -delete, you should explicitly specify -depth in order to avoid later surprises. Because -delete implies
-depth, you cannot usefully use -prune and -delete together.
-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command
until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name being processed
everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find.
Both of these constructions might need to be escaped (with a `\') or quoted to protect them from expansion by the shell.
See the EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched
file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the
-exec action; you should use the -execdir option instead.
-exec command {} +
This variant of the -exec action runs the specified command on the selected files, but the command line is built by append‐
ing each selected file name at the end; the total number of invocations of the command will be much less than the number of
matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of
`{}' is allowed within the command, and (when find is being invoked from a shell) it should be quoted (for example, '{}')
to protect it from interpretation by shells. The command is executed in the starting directory. If any invocation returns
a non-zero value as exit status, then find returns a non-zero exit status. If find encounters an error, this can sometimes
cause an immediate exit, so some pending commands may not be run at all. This variant of -exec always returns true.
-execdir command ;
-execdir command {} +
Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not normally the
directory in which you started find. As with -exec, the {} should be quoted if find is being invoked from a shell. This a
much more secure method for invoking commands, as it avoids race conditions during resolution of the paths to the matched
files. As with the -exec action, the `+' form of -execdir will build a command line to process more than one matched file,
but any given invocation of command will only list files that exist in the same subdirectory. If you use this option, you
must ensure that your $PATH environment variable does not reference `.'; otherwise, an attacker can run any commands they
like by leaving an appropriately-named file in a directory in which you will run -execdir. The same applies to having
entries in $PATH which are empty or which are not absolute directory names. If any invocation returns a non-zero value as
exit status, then find returns a non-zero exit status. If find encounters an error, this can sometimes cause an immediate
exit, so some pending commands may not be run at all. The result of the action depends on whether the + or the ; variant is
being used; -execdir command {} + always returns true, while -execdir command {} ; returns true only if command returns 0.
-fls file
True; like -ls but write to file like -fprint. The output file is always created, even if the predicate is never matched.
See the UNUSUAL FILENAMES section for information about how unusual characters in filenames are handled.
-fprint file
True; print the full file name into file file. If file does not exist when find is run, it is created; if it does exist,
it is truncated. The file names `/dev/stdout' and `/dev/stderr' are handled specially; they refer to the standard output
and standard error output, respectively. The output file is always created, even if the predicate is never matched. See
the UNUSUAL FILENAMES section for information about how unusual characters in filenames are handled.
-fprint0 file
True; like -print0 but write to file like -fprint. The output file is always created, even if the predicate is never
matched. See the UNUSUAL FILENAMES section for information about how unusual characters in filenames are handled.
-fprintf file format
True; like -printf but write to file like -fprint. The output file is always created, even if the predicate is never
matched. See the UNUSUAL FILENAMES section for information about how unusual characters in filenames are handled.
-ls True; list current file in ls -dils format on standard output. The block counts are of 1K blocks, unless the environment
variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used. See the UNUSUAL FILENAMES section for information
about how unusual characters in filenames are handled.
-ok command ;
Like -exec but ask the user first. If the user agrees, run the command. Otherwise just return false. If the command is
run, its standard input is redirected from /dev/null.
The response to the prompt is matched against a pair of regular expressions to determine if it is an affirmative or nega‐
tive response. This regular expression is obtained from the system if the `POSIXLY_CORRECT' environment variable is set,
or otherwise from find's message translations. If the system has no suitable definition, find's own definition will be
used. In either case, the interpretation of the regular expression itself will be affected by the environment variables
'LC_CTYPE' (character classes) and 'LC_COLLATE' (character ranges and equivalence classes).
-okdir command ;
Like -execdir but ask the user first in the same way as for -ok. If the user does not agree, just return false. If the
command is run, its standard input is redirected from /dev/null.
-print True; print the full file name on the standard output, followed by a newline. If you are piping the output of find into
another program and there is the faintest possibility that the files which you are searching for might contain a newline,
then you should seriously consider using the -print0 option instead of -print. See the UNUSUAL FILENAMES section for
information about how unusual characters in filenames are handled.
-print0
True; print the full file name on the standard output, followed by a null character (instead of the newline character that
-print uses). This allows file names that contain newlines or other types of white space to be correctly interpreted by
programs that process the find output. This option corresponds to the -0 option of xargs.
-printf format
True; print format on the standard output, interpreting `\' escapes and `%' directives. Field widths and precisions can be
specified as with the `printf' C function. Please note that many of the fields are printed as %s rather than %d, and this
may mean that flags don't work as you might expect. This also means that the `-' flag does work (it forces fields to be
left-aligned). Unlike -print, -printf does not add a newline at the end of the string. The escapes and directives are:
\a Alarm bell.
\b Backspace.
\c Stop printing from this format immediately and flush the output.
\f Form feed.
\n Newline.
\r Carriage return.
\t Horizontal tab.
\v Vertical tab.
\0 ASCII NUL.
\\ A literal backslash (`\').
\NNN The character whose ASCII code is NNN (octal).
A `\' character followed by any other character is treated as an ordinary character, so they both are printed.
%% A literal percent sign.
%a File's last access time in the format returned by the C `ctime' function.
%Ak File's last access time in the format specified by k, which is either `@' or a directive for the C `strftime' func‐
tion. The possible values for k are listed below; some of them might not be available on all systems, due to dif‐
ferences in `strftime' between systems.
@ seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
Time fields:
H hour (00..23)
I hour (01..12)
k hour ( 0..23)
l hour ( 1..12)
M minute (00..59)
p locale's AM or PM
r time, 12-hour (hh:mm:ss [AP]M)
S Second (00.00 .. 61.00). There is a fractional part.
T time, 24-hour (hh:mm:ss.xxxxxxxxxx)
+ Date and time, separated by `+', for example `2004-04-28+22:22:05.0'. This is a GNU extension. The time is
given in the current timezone (which may be affected by setting the TZ environment variable). The seconds
field includes a fractional part.
X locale's time representation (H:M:S). The seconds field includes a fractional part.
Z time zone (e.g., EDT), or nothing if no time zone is determinable
Date fields:
a locale's abbreviated weekday name (Sun..Sat)
A locale's full weekday name, variable length (Sunday..Saturday)
b locale's abbreviated month name (Jan..Dec)
B locale's full month name, variable length (January..December)
c locale's date and time (Sat Nov 04 12:02:33 EST 1989). The format is the same as for ctime(3) and so to pre‐
serve compatibility with that format, there is no fractional part in the seconds field.
d day of month (01..31)
D date (mm/dd/yy)
h same as b
j day of year (001..366)
m month (01..12)
U week number of year with Sunday as first day of week (00..53)
w day of week (0..6)
W week number of year with Monday as first day of week (00..53)
x locale's date representation (mm/dd/yy)
y last two digits of year (00..99)
Y year (1970...)
%b The amount of disk space used for this file in 512-byte blocks. Since disk space is allocated in multiples of the
filesystem block size this is usually greater than %s/512, but it can also be smaller if the file is a sparse file.
%c File's last status change time in the format returned by the C `ctime' function.
%Ck File's last status change time in the format specified by k, which is the same as for %A.
%d File's depth in the directory tree; 0 means the file is a starting-point.
%D The device number on which the file exists (the st_dev field of struct stat), in decimal.
%f File's name with any leading directories removed (only the last element).
%F Type of the filesystem the file is on; this value can be used for -fstype.
%g File's group name, or numeric group ID if the group has no name.
%G File's numeric group ID.
%h Leading directories of file's name (all but the last element). If the file name contains no slashes (since it is in
the current directory) the %h specifier expands to `.'.
%H Starting-point under which file was found.
%i File's inode number (in decimal).
%k The amount of disk space used for this file in 1K blocks. Since disk space is allocated in multiples of the
filesystem block size this is usually greater than %s/1024, but it can also be smaller if the file is a sparse file.
%l Object of symbolic link (empty string if file is not a symbolic link).
%m File's permission bits (in octal). This option uses the `traditional' numbers which most Unix implementations use,
but if your particular implementation uses an unusual ordering of octal permissions bits, you will see a difference
between the actual value of the file's mode and the output of %m. Normally you will want to have a leading zero on
this number, and to do this, you should use the # flag (as in, for example, `%#m').
%M File's permissions (in symbolic form, as for ls). This directive is supported in findutils 4.2.5 and later.
%n Number of hard links to file.
%p File's name.
%P File's name with the name of the starting-point under which it was found removed.
%s File's size in bytes.
%S File's sparseness. This is calculated as (BLOCKSIZE*st_blocks / st_size). The exact value you will get for an
ordinary file of a certain length is system-dependent. However, normally sparse files will have values less than
1.0, and files which use indirect blocks may have a value which is greater than 1.0. The value used for BLOCKSIZE
is system-dependent, but is usually 512 bytes. If the file size is zero, the value printed is undefined. On sys‐
tems which lack support for st_blocks, a file's sparseness is assumed to be 1.0.
%t File's last modification time in the format returned by the C `ctime' function.
%Tk File's last modification time in the format specified by k, which is the same as for %A.
%u File's user name, or numeric user ID if the user has no name.
%U File's numeric user ID.
%y File's type (like in ls -l), U=unknown type (shouldn't happen)
%Y File's type (like %y), plus follow symlinks: L=loop, N=nonexistent
%Z (SELinux only) file's security context.
%{ %[ %(
Reserved for future use.
A `%' character followed by any other character is discarded, but the other character is printed (don't rely on this, as
further format characters may be introduced). A `%' at the end of the format argument causes undefined behaviour since
there is no following character. In some locales, it may hide your door keys, while in others it may remove the final page
from the novel you are reading.
The %m and %d directives support the # , 0 and + flags, but the other directives do not, even if they print numbers.
Numeric directives that do not support these flags include G, U, b, D, k and n. The `-' format flag is supported and
changes the alignment of a field from right-justified (which is the default) to left-justified.
See the UNUSUAL FILENAMES section for information about how unusual characters in filenames are handled.
-prune True; if the file is a directory, do not descend into it. If -depth is given, false; no effect. Because -delete implies
-depth, you cannot usefully use -prune and -delete together.
-quit Exit immediately. No child processes will be left running, but no more paths specified on the command line will be pro‐
cessed. For example, find /tmp/foo /tmp/bar -print -quit will print only /tmp/foo. Any command lines which have been
built up with -execdir ... {} + will be invoked before find exits. The exit status may or may not be zero, depending on
whether an error has already occurred.
下記のようなオプションもある。
-printf
出力フォーマットを指定してファイルリストを出力する
コマンド解説③ grepコマンド
$ whatis grep
grep (1) - print lines matching a pattern
ファイルの中身から、パターンにマッチする文字列を検索するコマンド。
検証バージョンはこちら。
$ grep --version
grep (GNU grep) 3.1
基本的な使い方
# 指定したファイルから、パターンにマッチする文字列を検索
$ grep -E 'dependency.*javax' spring-framework/build.gradle
dependency "com.sun.activation:javax.activation:1.2.0"
dependency "com.sun.mail:javax.mail:1.6.2"
dependency "javax.activation:javax.activation-api:1.2.0"
dependency "javax.annotation:javax.annotation-api:1.3.2"
・・・
# サブディレクトリ配下の全てのファイルから、パターンにマッチする文字列を検索
$ grep -E -r 'public interface' spring-framework/spring-core/src/main/java/
spring-framework/spring-core/src/main/java/org/springframework/asm/Opcodes.java:public interface Opcodes {
spring-framework/spring-core/src/main/java/org/springframework/util/MultiValueMap.java:public interface MultiValueMap<K, V> extends Map<K, List<V>> {
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java:public interface FailureCallback {
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java:public interface ListenableFuture<T> extends Future<T> {
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java:public interface ListenableFutureCallback<T> extends SuccessCallback<T>, FailureCallback {
・・・
全体を俯瞰してみる
grepコマンドで指定できるオプションは、大きく3種類。
- 使用する正規表現タイプの指定
- 検索方法の指定(大文字小文字を区別しない、単語で検索など)
- 出力方法の指定(行番号の表示、ファイル名の表示など)
使い方も素直なので、あまり迷うところもない印象。
まずポイントとなるのは、正規表現タイプに拡張正規表現(ERE)、もしくはPerl正規表現を選ぶこと。
デフォルトの基本正規表現(BRE)より、表現力も書きやすさも格段にアップする。
他のコマンドでも使用できる汎用性を重視するなら拡張正規表現(ERE)、表現力を追求するならPerl正規表現を使いましょう。
あとは、サブディレクトリも対象にgrepを実行すると検索結果が大量に出ることが多いので、出力情報をオプションで適切に絞る方法を覚えると、効率的に結果を把握できる。
指定できるオプション数は全部で46個。
カテゴリ | オプション数 | 備考 |
---|---|---|
正規表現タイプ指定 | 4 | |
検索方法指定 | 19 | |
出力方法指定 | 21 | |
その他 | 2 | --helpと--version |
findの後だと、少なく見えてしまいますね。
どんどん見ていきましょう。
正規表現タイプ指定
検索に使用する正規表現タイプとして、下記のいずれかを指定できる。
-
-G
基本正規表現(BRE)(デフォルト) -
-E
拡張正規表現(ERE) -
-P
Perl正規表現 -
-F
正規表現を使用せずに固定文字列として検索
正規表現を使用する場合は、まずは拡張正規表現(ERE)を選んでおけば間違いない。
制御文字をそのまま検索したい場合は、固定文字列として検索するのが便利。
正規表現タイプ指定関連の全オプション
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (ERE, see below).
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings (instead of regular expressions), separated by newlines, any of which is to be
matched.
-G, --basic-regexp
Interpret PATTERN as a basic regular expression (BRE, see below). This is the default.
-P, --perl-regexp
Interpret the pattern as a Perl-compatible regular expression (PCRE). This is experimental and grep -P may warn of
unimplemented features.
-E
や-F
の代わりにegrepやfgrepというコマンドもあるが非推奨。
検索方法指定
主に下記のようなことを指定可能。
- 大文字小文字を区別しない
- 単語として検索
- サブディレクトリ配下の全てのファイルから検索
- 検索対象、検索対象外とするファイルの指定
# -i 大文字小文字を区別しない
$ cat hoge.txt
abc
ABC
Abc
$ grep 'abc' hoge.txt
abc
$ grep -i 'abc' hoge.txt
abc
ABC
Abc
# -w 単語単位で検索
$ cat hoge.txt
abcdefghi
abc def ghi
$ grep 'def' hoge.txt
abcdefghi
abc def ghi
$ grep -w 'def' hoge.txt
abc def ghi
# -x パターンと完全一致する行を検索
$ cat hoge.txt
abc
abcdef
def
defghi
$ grep 'def' hoge.txt
abcdef
def
defghi
$ grep -x 'def' hoge.txt
def
# -v パターンとマッチしない行を検索
$ cat hoge.txt
abc
def
ghi
$ grep 'abc' hoge.txt
abc
$ $ grep -v 'abc' hoge.txt
def
ghi
# -e 正規表現パターンを複数指定する。指定したパターンのいずれかに合致する行を表示
$ cat hoge.txt
abc
def
ghi
jkl
$ grep -e 'abc' -e 'ghi' hoge.txt
abc
ghi
## -fで、正規表現パターンをコマンドラインではなくファイルから指定することもできる
# -r サブディレクトリ配下の全てのファイルから、パターンにマッチする文字列を検索
## リンク先はコマンドラインで指定したもの以外は検索しない
$ grep -r 'public interface' spring-framework/spring-core/src/main/java/
spring-framework/spring-core/src/main/java/org/springframework/asm/Opcodes.java:public interface Opcodes {
spring-framework/spring-core/src/main/java/org/springframework/util/MultiValueMap.java:public interface MultiValueMap<K, V> extends Map<K, List<V>> {
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java:public interface FailureCallback {
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java:public interface ListenableFuture<T> extends Future<T> {
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java:public interface ListenableFutureCallback<T> extends SuccessCallback<T>, FailureCallback {
・・・
## 全てのリンク先を検索したい場合は、-Rを使用する
# --exclude=GLOB 指定したファイルを検索対象外とする
# --exclude-dir=GLOB 指定したディレクトリを検索対象外とする
$ grep -r 'abc' .
./piyo/piyopiyo.txt:abc
./piyo.txt:abc
./hoge/hogehoge.txt:abc
./hoge.txt:abc
$ grep -r --exclude=piyo*.txt 'abc' .
./hoge/hogehoge.txt:abc
./hoge.txt:abc
$ grep -r --exclude-dir=piyo 'abc' .
./piyo.txt:abc
./hoge/hogehoge.txt:abc
./hoge.txt:abc
## --exclude-from=FILEで、検索対象外とするファイルを
## コマンドラインではなくファイルから指定することもできる
# --include=GLOB 指定したファイルのみを検索対象とする
$ grep -r 'abc' .
./piyo/piyopiyo.txt:abc
./piyo.txt:abc
./hoge/hogehoge.txt:abc
./hoge.txt:abc
$ grep -r --include=piyo*.txt 'abc' .
./piyo/piyopiyo.txt:abc
./piyo.txt:abc
検索方法指定関連の全オプション
-e PATTERN, --regexp=PATTERN
Use PATTERN as the pattern. If this option is used multiple times or is combined with the -f (--file) option, search for
all patterns given. This option can be used to protect a pattern beginning with “-”.
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. If this option is used multiple times or is combined with the -e (--regexp)
option, search for all patterns given. The empty file contains zero patterns, and therefore matches nothing.
-i, --ignore-case
Ignore case distinctions, so that characters that differ only in case match each other.
-v, --invert-match
Invert the sense of matching, to select non-matching lines.
-w, --word-regexp
Select only those lines containing matches that form whole words. The test is that the matching substring must either be
at the beginning of the line, or preceded by a non-word constituent character. Similarly, it must be either at the end of
the line or followed by a non-word constituent character. Word-constituent characters are letters, digits, and the
underscore. This option has no effect if -x is also specified.
-x, --line-regexp
Select only those matches that exactly match the whole line. For a regular expression pattern, this is like parenthesizing
the pattern and then surrounding it with ^ and $.
-y Obsolete synonym for -i.
-a, --text
Process a binary file as if it were text; this is equivalent to the --binary-files=text option.
--binary-files=TYPE
If a file's data or metadata indicate that the file contains binary data, assume that the file is of type TYPE. Non-text
bytes indicate binary data; these are either output bytes that are improperly encoded for the current locale, or null input
bytes when the -z option is not given.
By default, TYPE is binary, and when grep discovers that a file is binary it suppresses any further output, and instead
outputs either a one-line message saying that a binary file matches, or no message if there is no match.
If TYPE is without-match, when grep discovers that a file is binary it assumes that the rest of the file does not match;
this is equivalent to the -I option.
If TYPE is text, grep processes a binary file as if it were text; this is equivalent to the -a option.
When type is binary, grep may treat non-text bytes as line terminators even without the -z option. This means choosing
binary versus text can affect whether a pattern matches a file. For example, when type is binary the pattern q$ might
match q immediately followed by a null byte, even though this is not matched when type is text. Conversely, when type is
binary the pattern . (period) might not match a null byte.
Warning: The -a option might output binary garbage, which can have nasty side effects if the output is a terminal and if
the terminal driver interprets some of it as commands. On the other hand, when reading files whose text encodings are
unknown, it can be helpful to use -a or to set LC_ALL='C' in the environment, in order to find more matches even if the
matches are unsafe for direct display.
-D ACTION, --devices=ACTION
If an input file is a device, FIFO or socket, use ACTION to process it. By default, ACTION is read, which means that
devices are read just as if they were ordinary files. If ACTION is skip, devices are silently skipped.
-d ACTION, --directories=ACTION
If an input file is a directory, use ACTION to process it. By default, ACTION is read, i.e., read directories just as if
they were ordinary files. If ACTION is skip, silently skip directories. If ACTION is recurse, read all files under each
directory, recursively, following symbolic links only if they are on the command line. This is equivalent to the -r
option.
--exclude=GLOB
Skip any command-line file with a name suffix that matches the pattern GLOB, using wildcard matching; a name suffix is
either the whole name, or any suffix starting after a / and before a +non-/. When searching recursively, skip any subfile
whose base name matches GLOB; the base name is the part after the last /. A pattern can use *, ?, and [...] as wildcards,
and \ to quote a wildcard or backslash character literally.
--exclude-from=FILE
Skip files whose base name matches any of the file-name globs read from FILE (using wildcard matching as described under
--exclude).
--exclude-dir=GLOB
Skip any command-line directory with a name suffix that matches the pattern GLOB. When searching recursively, skip any
subdirectory whose base name matches GLOB. Ignore any redundant trailing slashes in GLOB.
-I Process a binary file as if it did not contain matching data; this is equivalent to the --binary-files=without-match
option.
--include=GLOB
Search only files whose base name matches GLOB (using wildcard matching as described under --exclude).
-r, --recursive
Read all files under each directory, recursively, following symbolic links only if they are on the command line. Note that
if no file operand is given, grep searches the working directory. This is equivalent to the -d recurse option.
-R, --dereference-recursive
Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
-U, --binary
Treat the file(s) as binary. By default, under MS-DOS and MS-Windows, grep guesses whether a file is text or binary as
described for the --binary-files option. If grep decides the file is a text file, it strips the CR characters from the
original file contents (to make regular expressions with ^ and $ work correctly). Specifying -U overrules this guesswork,
causing all files to be read and passed to the matching mechanism verbatim; if the file is a text file with CR/LF pairs at
the end of each line, this will cause some regular expressions to fail. This option has no effect on platforms other than
MS-DOS and MS-Windows.
-a
で、バイナリファイルをテキストファイルとして検索することができる。テキストファイルがバイナリファイルだと誤判定される場合に便利。
出力方法指定
主に下記のようなことを指定可能。
- 行番号を表示
- ファイル名の表示
- マッチした行数のみ表示
- マッチしたファイル名のみ表示
- マッチした前後の行も合わせて表示
- マッチさせる行数の制限
# -n 行番号を表示する
# -n バイトオフセットを表示する
# -T 行番号と検索結果をタブで揃えて表示する
$ cat hoge.txt
aaa
bbb
ccc
ddd
eee
$ grep -E -n '[a|c|e]' hoge.txt
1:aaa
3:ccc
5:eee
$ grep -E -b '[a|c|e]' hoge.txt
0:aaa
8:ccc
16:eee
$ grep -E -bT '[a|c|e]' hoge.txt
0: aaa
8: ccc
16: eee
# -c マッチした行数のみ表示する
$ cat hoge.txt
aaa
bbb
aaa
bbb
aaa
bbb
$ grep -c 'aaa' hoge.txt
3
# -H 検索結果と合わせてファイル名も表示する(複数ファイル検索時のデフォルト)
# -h 検索結果にファイル名を表示しない(単一ファイル検索時のデフォルト)
$ cat hoge.txt
abc
$ cat piyo.txt
abc
## 単一ファイル検索
$ grep 'abc' hoge.txt
abc
$ grep -H 'abc' hoge.txt
hoge.txt:abc
## 複数ファイル検索
$ grep 'abc' hoge.txt piyo.txt
hoge.txt:abc
piyo.txt:abc
$ grep -h 'abc' hoge.txt piyo.txt
abc
abc
# -l マッチしたファイル名のみ表示する
$ grep -lr 'public interface' spring-framework/spring-core/src/main/java/
spring-framework/spring-core/src/main/java/org/springframework/asm/Opcodes.java
spring-framework/spring-core/src/main/java/org/springframework/util/MultiValueMap.java
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java
spring-framework/spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java
・・・
# -L マッチしなかったファイル名のみ表示する
$ grep -Lr 'public interface' spring-framework/spring-core/src/main/java/
spring-framework/spring-core/src/main/java/org/springframework/asm/ClassWriter.java
spring-framework/spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java
spring-framework/spring-core/src/main/java/org/springframework/asm/MethodVisitor.java
spring-framework/spring-core/src/main/java/org/springframework/asm/Label.java
spring-framework/spring-core/src/main/java/org/springframework/asm/ModuleWriter.java
・・・
# -o マッチした部分だけを表示する
$ cat hoge.txt
abcdefghi
defghijkl
$ grep -E 'g.*' hoge.txt
abcdefghi
defghijkl
$ grep -E -o 'g.*' hoge.txt
ghi
ghijkl
# -B NUM マッチした行の前の行をNUMで指定した行数分表示する
# -A NUM マッチした行の後の行をNUMで指定した行数分表示する
# -C NUM マッチした行の前後の行をNUMで指定した行数分表示する(-NUMでも可)
$ cat hoge.txt
a
b
c
d
e
f
g
$ grep -B 2 'd' hoge.txt
b
c
d
$ grep -A 2 'd' hoge.txt
d
e
f
$ grep -C 2 'd' hoge.txt
b
c
d
e
f
$ grep -2 'd' hoge.txt
b
c
d
e
f
## ハイフンと数字のみの指定でも前後の行を表示できる
# -m NUM マッチさせる行数を制限する
$ cat hoge.txt
abc
def
abc
def
abc
def
## -mを指定しない場合
$ grep -n 'abc' hoge.txt
1:abc
3:abc
5:abc
## 全ての一致箇所が表示される
## -mを指定をした場合
$ grep -n -m 2 'abc' hoge.txt
1:abc
3:abc
## 指定した行数分しか検索しない
# -s エラーメッセージを表示しない
$ tree
.
├── hoge
├── hoge.txt
├── piyo
└── piyo.txt
## -sを指定しない場合
$ grep 'abc' *
grep: hoge: Is a directory
hoge.txt:abc
grep: piyo: Is a directory
piyo.txt:abc
## ディレクトリを検索するとエラーメッセージが表示される
## -sを指定した場合
$ grep -s 'abc' *
hoge.txt:abc
piyo.txt:abc
## エラーメッセージは表示されない
出力方法指定関連の全オプション
-c, --count
Suppress normal output; instead print a count of matching lines for each input file. With the -v, --invert-match option
(see below), count non-matching lines.
--color[=WHEN], --colour[=WHEN]
Surround the matched (non-empty) strings, matching lines, context lines, file names, line numbers, byte offsets, and
separators (for fields and groups of context lines) with escape sequences to display them in color on the terminal. The
colors are defined by the environment variable GREP_COLORS. The deprecated environment variable GREP_COLOR is still
supported, but its setting does not have priority. WHEN is never, always, or auto.
-L, --files-without-match
Suppress normal output; instead print the name of each input file from which no output would normally have been printed.
The scanning will stop on the first match.
-l, --files-with-matches
Suppress normal output; instead print the name of each input file from which output would normally have been printed. The
scanning will stop on the first match.
-m NUM, --max-count=NUM
Stop reading a file after NUM matching lines. If the input is standard input from a regular file, and NUM matching lines
are output, grep ensures that the standard input is positioned to just after the last matching line before exiting,
regardless of the presence of trailing context lines. This enables a calling process to resume a search. When grep stops
after NUM matching lines, it outputs any trailing context lines. When the -c or --count option is also used, grep does not
output a count greater than NUM. When the -v or --invert-match option is also used, grep stops after outputting NUM non-
matching lines.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.
-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error
was detected. Also see the -s or --no-messages option.
-s, --no-messages
Suppress error messages about nonexistent or unreadable files.
-b, --byte-offset
Print the 0-based byte offset within the input file before each line of output. If -o (--only-matching) is specified,
print the offset of the matching part itself.
-H, --with-filename
Print the file name for each match. This is the default when there is more than one file to search.
-h, --no-filename
Suppress the prefixing of file names on output. This is the default when there is only one file (or only standard input)
to search.
--label=LABEL
Display input actually coming from standard input as input coming from file LABEL. This is especially useful when
implementing tools like zgrep, e.g., gzip -cd foo.gz | grep --label=foo -H something. See also the -H option.
-n, --line-number
Prefix each line of output with the 1-based line number within its input file.
-T, --initial-tab
Make sure that the first character of actual line content lies on a tab stop, so that the alignment of tabs looks normal.
This is useful with options that prefix their output to the actual content: -H,-n, and -b. In order to improve the
probability that lines from a single file will all start at the same column, this also causes the line number and byte
offset (if present) to be printed in a minimum size field width.
-u, --unix-byte-offsets
Report Unix-style byte offsets. This switch causes grep to report byte offsets as if the file were a Unix-style text file,
i.e., with CR characters stripped off. This will produce results identical to running grep on a Unix machine. This option
has no effect unless -b option is also used; it has no effect on platforms other than MS-DOS and MS-Windows.
-Z, --null
Output a zero byte (the ASCII NUL character) instead of the character that normally follows a file name. For example, grep
-lZ outputs a zero byte after each file name instead of the usual newline. This option makes the output unambiguous, even
in the presence of file names containing unusual characters like newlines. This option can be used with commands like find
-print0, perl -0, sort -z, and xargs -0 to process arbitrary file names, even those that contain newline characters.
-A NUM, --after-context=NUM
Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between
contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.
-B NUM, --before-context=NUM
Print NUM lines of leading context before matching lines. Places a line containing a group separator (--) between
contiguous groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.
-C NUM, -NUM, --context=NUM
Print NUM lines of output context. Places a line containing a group separator (--) between contiguous groups of matches.
With the -o or --only-matching option, this has no effect and a warning is given.
--line-buffered
Use line buffering on output. This can cause a performance penalty.
-z, --null-data
Treat input and output data as sequences of lines, each terminated by a zero byte (the ASCII NUL character) instead of a
newline. Like the -Z or --null option, this option can be used with commands like sort -z to process arbitrary file names.
-z
で、入力と出力のデータをnull文字(¥0)区切りとすることができる。空白や制御文字を含むファイル名を扱う場合に使用する。
まとめ
予想していた通り、ls、find、grepコマンドはかなり奥の深いコマンド達でしたね。
この記事を書くためにこれらのコマンドとしばらく向き合ったおかげで、かなり仲良くなれた気がします。
それぞれのコマンドだけでも十分強力でしたが、これらのコマンドを-execやパイプを使って組み合わせて使えば、もうファイル検索は自由自在ですね。
みなさんもどんどん活用して、ls、find、grepコマンドと生涯の友となりましょう!
参考
http://man7.org/linux/man-pages/index.html
https://linuxjm.osdn.jp/