いろいろ備忘録日記

主に .NET とか Go とか Python絡みのメモを公開しています。

findコマンドで正規表現を使う (regextype, regex)

概要

小ネタ。よく忘れるのでメモメモ。知ってるとちょっと便利です。

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] =====

参考情報

qiita.com

www.gnu.org


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com