概要
小ネタ。よく忘れるのでメモメモ。知ってるとちょっと便利です。
find コマンドは、よく利用するコマンドですが、-name
オプションの指定には シェル のワイルドカードと同じ指定しかできません。もう少し、細かい絞り込みがしたい場合は別途パイプでつないだりしているのをよく見かけます。
実は find コマンドでも正規表現で条件を指定することができます。
以下の2つのオプションを指定します。
- regextype
- regex
regextype で、使用する正規表現のタイプを設定します。いろいろあるのですが、自分がよく利用するのは以下の2つ。
- posix-basic
- posix-egrep
posix-basic が grep コマンドで -E
を付けていない場合、posix-egrep が grep コマンドで -E
を付けている場合と覚えるとわかりやすいです。
タイプを指定した後に、regex オプションで正規表現を指定します。
注意点として、find コマンドの場合は部分一致にならないので、パスも含めて一致させる必要があります。
なので、通常は前後に .*
とかを付与することが多いですね。
サンプル
#!/usr/bin/env bash # # REFERENCES: # - https://www.greptips.com/posts/301/ # - https://qiita.com/richmikan@github/items/b6fb641e5b2b9af3522e # - https://www.gnu.org/software/findutils/manual/html_node/find_html/Regular-Expressions.html # basedirpath=/tmp/try-linux/findregex rm -rf "${basedirpath}" mkdir -p "${basedirpath}" ## テスト用のファイルを生成 # seq -w 1 100 | xargs -I{seq} touch "${basedirpath}/findregex_{seq}.txt" echo $(ls -1 "${basedirpath}" | wc -l) 'files was generated' ## 基本正規表現 (BRE) メタ文字セットで検索 # # 基本正規表現 (BRE) で検索する場合は # -regextype posix-basic # を使用する。 # # これは、 grep で -E をつけない場合と同じ # # どの正規表現モードを利用するかを -regextype で指定して # 実際の正規表現は -regex で指定する。 # # この際、注意点として「部分一致」とはならないことに注意 # find の結果は そこまでのディレクトリも含めたパスとなっているので # ファイル名だけの正規表現を指定しても何もヒットしない。 # # なので、通常は 先頭と必要であれば末尾に .* を付与したりする。 # echo '[posix-basic1] -----------------------------------------------' find "${basedirpath}" -type f -regextype posix-basic -regex ".*findregex_[0]\{2\}[0-3]\.txt$" -print # BRE では、繰り返し指定子はエスケープしないと使えないので、エスケープしない場合だとヒットしない # ERE では、これらはエスケープ不要となっている echo '[posix-basic2] -----------------------------------------------' find "${basedirpath}" -type f -regextype posix-basic -regex ".*findregex_[0]{2}[0-3]\.txt$" -print ## 拡張正規表現 (ERE) メタ文字セットで検索 # # 拡張正規表現 (ERE) で検索する場合は # -regextype posix-egrep # を使用する。 # # これは、 grep で -E を付けた場合と同じ # echo '[posix-egrep1] -----------------------------------------------' find "${basedirpath}" -type f -regextype posix-egrep -regex ".*findregex_[01][056]{2}\.txt$" -print echo '[posix-egrep2] -----------------------------------------------' find "${basedirpath}" -type f -regextype posix-egrep -regex ".*findregex_10+\.txt$" -print ## find と xargs の連携 # echo '[find-xargs] -----------------------------------------------' find "${basedirpath}" \ -type f \ -regextype posix-egrep \ -regex ".*findregex_0[0-9]7\.txt" \ -print0 \ | xargs -0 -I{} rm -v -f {} echo $(ls -1 "${basedirpath}" | wc -l) 'files'
try-linux/find_regex.sh at master · devlights/try-linux · GitHub
実行すると以下のようになります。
gitpod /workspace/try-linux $ make ENTER EXAMPLE NAME: find_regex [INPUT ] find_regex [TARGET] find_regex [SCRIPT] basic/find/find_regex.sh ===== START [basic/find/find_regex.sh] ===== 100 files was generated [posix-basic1] ----------------------------------------------- /tmp/try-linux/findregex/findregex_003.txt /tmp/try-linux/findregex/findregex_002.txt /tmp/try-linux/findregex/findregex_001.txt [posix-basic2] ----------------------------------------------- [posix-egrep1] ----------------------------------------------- /tmp/try-linux/findregex/findregex_100.txt /tmp/try-linux/findregex/findregex_066.txt /tmp/try-linux/findregex/findregex_065.txt /tmp/try-linux/findregex/findregex_060.txt /tmp/try-linux/findregex/findregex_056.txt /tmp/try-linux/findregex/findregex_055.txt /tmp/try-linux/findregex/findregex_050.txt /tmp/try-linux/findregex/findregex_006.txt /tmp/try-linux/findregex/findregex_005.txt [posix-egrep2] ----------------------------------------------- /tmp/try-linux/findregex/findregex_100.txt [find-xargs] ----------------------------------------------- removed '/tmp/try-linux/findregex/findregex_097.txt' removed '/tmp/try-linux/findregex/findregex_087.txt' removed '/tmp/try-linux/findregex/findregex_077.txt' removed '/tmp/try-linux/findregex/findregex_067.txt' removed '/tmp/try-linux/findregex/findregex_057.txt' removed '/tmp/try-linux/findregex/findregex_047.txt' removed '/tmp/try-linux/findregex/findregex_037.txt' removed '/tmp/try-linux/findregex/findregex_027.txt' removed '/tmp/try-linux/findregex/findregex_017.txt' removed '/tmp/try-linux/findregex/findregex_007.txt' 90 files ===== END [basic/find/find_regex.sh] =====
参考情報
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場