条件を指定してファイルを検索する

find command 1/N

公開日: 2023-01-01
更新日: 2023-08-16

  Table of Contents

find command

Def: find command

1
% find [option] <search-directory> <search-condition>
  • findコマンドは, 探索範囲を指定して指定してファイルを検索するコマンド
  • ファイルの種類や更新日時など検索条件が設定可能
  • マッチしたファイルに対してコマンドを実行させることも可能
  • アクセス権がないディレクトリ(=実行権限)の中は検索できない

ホームディレクトリ直下でファイル名 or ディレクトリ名に “bash” を含むファイルを検索する場合は

1
2
3
4
5
6
7
8
9
10
## ワイルドカードを用いる場合はダブルクォート必要
% find ~ -maxdepth 1 -name "*bash*"
/home/hoshino_kirby/.bashrc
/home/hoshino_kirby/.bash_history
/home/hoshino_kirby/.bash_logout

% find ~ -maxdepth 1 -name "*bash*" 2>/dev/null
/home/hoshino_kirby/.bashrc
/home/hoshino_kirby/.bash_history
/home/hoshino_kirby/.bash_logout

権限ない検索場所を検索範囲に含めてしまうと Permission denied というエラーが返ってきます. それを2>/dev/nullヌルデバイスにリダイレクトするという形で実行するスクリプトはよく見られます.

よく使用されるoption

option自体は検索式ではなく, シンボリックリンクをたどる or notというfindコマンドの挙動を指定するものです

-P シンボリックリンクをたどらない(デフォルト)
-L 全てのシンボリックリンクをたどる

検索条件式

permission条件で検索条件を設定する-permなどfindコマンドには便利な条件設定があります. 以下では具体例を交えつつ, 条件式オプションを紹介します.

ファイルタイプの指定

1
2
## ファイルタイプの指定を検索条件に含めたいとき
% find <search directory> -type <file type>

-type <file type>で検索対象のファイルタイプを絞ることができます. 指定できるファイルタイプは以下です:

f ファイル
d ディレクトリ
l シンボリックリンク

日数による検索

findコマンドでは日数による検索ができますがどのような日数が指定できるかは以下となります:

-atime 指定した日数をもとに, 最終アクセスされたファイルを検索
-mtime 指定した日数をもとに, 最終更新されたファイルを検索
1
2
3
4
5
6
7
8
9
10
11
## 7日前に最終更新したファイル数
% find /etc -type f -mtime 7 2>/dev/null | wc -l
6

## 7日以内未満に最終更新したファイル数
% find /etc -type f -mtime -7 2>/dev/null | wc -l
16

## 7日以上前(7日目は含まない)に最終更新したファイル数
% find /etc -type f -mtime +7 2>/dev/null | wc -l
2019

探索の深さの指定

-maxdepthに階層数をしていすることで探索の深さを指定することができます.

1
2
3
4
5
6
7
## home directory以下階層3までで探索する場合
% find ~ -maxdepth 3 -name "*bash*"
/home/hoshino_kirby/.bashrc
/home/hoshino_kirby/.bash_history
/home/hoshino_kirby/.vscode/extensions/rogalmic.bash-debug-0.3.9
/home/hoshino_kirby/.pyenv/test/test_helper.bash
/home/hoshino_kirby/.pyenv/src/bash.h

ファイルの所有者の指定

-uid-userを検索式で指定することによってファイルやディレクトリの所有者ベースで検索することができます

1
2
3
4
5
# uidベースで検索
% find /tmp -uid 0

# user-nameベースで検索
% find /tmp -user root

除外対象を指定する

<除外条件> -prune -o <検索条件> -print0 と組み合わせることで除外条件と検索条件を組み合わせてファイルリストを出力することができます.

<条件> -purne 条件1に合致したら何もしない
-o or
-print0 結果を出力する

home directory 直下でドットディレクトリ以外の一週間以内に更新があったディレクトリを出力したいとします

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## ドットディレクトリ以外の一週間以内に更新があったディレクトリ
% find ~/ -maxdepth 1 -mindepth 1 -name ".*" -prune -o \( -type d -mtime -7 -print \)
/home/hoshino_kirby/Downloads
/home/hoshino_kirby/Templates
/home/hoshino_kirby/Documents

## 一週間以内に更新があったディレクトリ
% find ~/ -maxdepth 1 -mindepth 1 \( -type d -mtime -7 -print \) 
/home/hoshino_kirby/Downloads
/home/hoshino_kirby/Templates
/home/hoshino_kirby/.cache
/home/hoshino_kirby/.zoom
/home/hoshino_kirby/.config
/home/hoshino_kirby/Documents

ディレクトリごとに検索条件を分けてワンライナーで出力したい場合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
% tree
.
├── dir_a
│   ├── file_1
│   └── file_2
├── dir_b
│   ├── dir_a
│   │   └── file_1
│   ├── dir_b
│   │   ├── file_1
│   │   └── file_2`-perm /4000`
│   ├── file_1
│   └── file_2
└── dir_c
    ├── dir_b
    │   ├── dir_a
    │   │   └── file_1
    │   ├── file_1
    │   └── file_2
    └── file1
  • dir_a, dir_bは直下のファイルのみ出力したい
  • dir_cは, 所属するすべてのファイルを出力したい

という条件を考えます. この場合, && をうまく使いこなすことで上記ファイルリストを出力することができます.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
% find ./dir_[ab] -maxdepth 1 -type f && find ./dir_c -type f 
./dir_a/file_2
./dir_a/file_1
./dir_b/file_2
./dir_b/file_1
./dir_c/file1
./dir_c/dir_b/file_2
./dir_c/dir_b/dir_a/file_1
./dir_c/dir_b/file_1

## sortなど標準出力結果をパイプでつなぎたい場合
% (find ./dir_[ab] -maxdepth 1 -type f && find ./dir_c -type f ) | sort
./dir_a/file_1
./dir_a/file_2
./dir_b/file_1
./dir_b/file_2
./dir_c/dir_b/dir_a/file_1
./dir_c/dir_b/file_1
./dir_c/dir_b/file_2
./dir_c/file1

ディレクトリ直下のファイル数を表示したい場合

応用編ですが, findの検索結果を用いてファイル数計算などのスクリプトを走らせたい場合, xargsと組み合わせることで複雑な処理も実行できます.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## ディレクトリ直下のファイル数を表示したい場合
% find /var/log -type d 2>/dev/null | xargs -I@ bash -c 'echo "@,$(find "@" -maxdepth 1 -type f 2>/dev/null | wc -l)"'
/var/log,90
/var/log/apache2,11
/var/log/journal,0
/var/log/journal/adasdasdasdas,37
/var/log/cups,8
/var/log/speech-dispatcher,0
/var/log/dist-upgrade,0
/var/log/installer,9
/var/log/gdm3,0
/var/log/unattended-upgrades,6
/var/log/openvpn,0
/var/log/apt,5

file sizeで検索を実行し, 対象のファイル名とディスク使用量を表示する

-size検索条件式をもちいることでfile sizeを条件に検索することができます.

1
2
3
4
5
6
7
8
9
## 10MB以上のファイル
% find ~/Desktop -size +10M -type f

## 10MB未満のファイル
% find ~/Desktop -size -10M -type f

## 10MB以上のcsvファイルのファイル名とディスク使用量の出力
% find ~/Desktop -size +10M -type f | xargs -i@ bash -c 'echo $(basename "@"),$(du -h "@" | cut -f1)' | egrep "csv,"
test_total.csv,12M

root権限で実行されるファイル一覧の検索

permission条件で検索条件を設定する-permを用いるとroot権限で実行されるファイル一覧の検索が可能になります.

  • -perm /4000 or -perm -4000と指定するとSUIDビットが立っているファイルを検索
  • -perm 4000と指定するとpermissionが4000となっているファイルを検索()
1
2
3
4
5
# /usr/bin以下でroot権限で実行されるファイル一覧の検索する場合
% find /usr/bin -uid 0 -perm /4000 -type f

# usernameで指定する場合
% find /usr/bin -user root -perm /4000 -type f

Refernces



Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)