解説
同じ名前でもフォルダーは除きたい:findの名前・種類・深さを分けよう
*.txtに合うものを探すとき、ファイル名だけでなく種類と探索範囲も指定する。隠しファイルや下の階層を含む小さな練習で確認する。

拡張子がtxtのファイルだけを探したい。名前だけで検索すると、同じ末尾のフォルダーや、下の階層まで含むことがあるよ。findでは「どこから」「どの深さまで」「どの種類を」「どんな名前で」探すかを分けられる。
今回はGNU findutils 4.10.0とBashを使う。新しい空の練習フォルダーで、架空のファイルだけを作る。名前を表示する作例で、削除や移動はしないよ。
練習する構成を用意する
mkdir docs archive.txt
printf 'one\n' > report.txt
printf 'hidden\n' > .memo.txt
printf 'nested\n' > docs/report.txt
printf 'note\n' > note.md
archive.txtは、今回は名前の末尾がtxtのフォルダー。docsの中にもreport.txtを置き、隠しファイルの.memo.txtも用意する。この四つの違いを区別できるかを確かめよう。
mkdirや>は同名の場所があると想定外の結果になり得るので、既存フォルダーの中へそのまま貼り付けず、空の練習場所か確認してね。
直下の通常ファイルだけを探す
find . -maxdepth 1 -type f -name '*.txt'
| 指定 | 今回の役割 |
|---|---|
| . | 今いるフォルダーを探索の起点にする |
| -maxdepth 1 | 起点の直下までにする |
| -type f | 通常ファイルを対象にする |
| -name '*.txt' | 名前のパターンを指定する |
期待する結果は./report.txtと./.memo.txt。表示順は前提にしないでね。archive.txtはフォルダーなので除かれ、docs/report.txtは深さの条件で除かれる。
引用符は、シェルに先に展開させないため
'*.txt'を引用符で囲むのは、*をシェルではなくfindのパターンとして渡すためだよ。囲まないと、実行する場所のファイル名へ先に置き換わることがある。
今回のGNU findでは、-nameの*はドットで始まる.memo.txtにも一致する。シェルの通常のワイルドカード展開と、同じものだと決めつけないようにしよう。
深さの条件だけを外して比べる
find . -type f -name '*.txt'
今度はdocs/report.txtも対象になる。-type fは残しているので、archive.txtというフォルダー自体は対象外のままだよ。条件を一つだけ変えると、何が結果へ影響したかを追いやすい。
権限で読めない場所がある場合などは、結果の行だけでなくエラーも確認する。エラーが出た検索を、全範囲の確認が終わった結果として扱わないようにしよう。
練習の確認ポイント
編集部では一時フォルダーで、直下の2ファイルと、深さ制限なしの3ファイルを集合として確認し、入力を変えないことも確かめた。BSD版など別実装のオプションまで検証したものではないよ。
作業場所の確認はpwdとcdの基本、引用符の働きはワイルドカードと引用符も合わせて読んでみよう。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。