DESIGN / CODE / INFRA / AI

解説

同じ名前でもフォルダーは除きたい:findの名前・種類・深さを分けよう

*.txtに合うものを探すとき、ファイル名だけでなく種類と探索範囲も指定する。隠しファイルや下の階層を含む小さな練習で確認する。

同じ名前でもフォルダーは除きたい:findの名前・種類・深さを分けよう
保存リストを見る →
この記事の道しるべ 5項目

拡張子が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

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。