ファイル名を正規表現と一致させる行?

ファイル名を正規表現と一致させる行?

小さなスクリプトがあります。

#!/bin/bash
# test for regular expressions to match...
DIR="/search/path/"
NAME="FOO[0-9][0-9]_<bar|dog|cat>"

for FILE in `find ${DIR} -maxdepth 1 -type f -name "*\.[dD][oO][cC]"` 
do
    BASENAME=`basename ${FILE}`
    FILENAME="${BASENAME%.*}"

    if [[ "${FILENAME}" == ${NAME} ]]
    then
            echo "Found $FILENAME"
    else
            echo "$FILENAME not matching..!"
    fi

done

このスクリプトでは、、、またはFOO[0-9[0-9]_で始まるすべてのファイルを一致させようとします。しかし、またはなどの他のものがある場合は、bardogcatbogcogcarいいえマッチ。

これは[a-z][a-z][a-z]一致します...

私は同様のことを試しました。

NAME="FOO[0-9][0-9]_(bar|dog|cat)"
or
NAME="FOO[0-9][0-9]_bar|dog|cat"
or
NAME="FOO[0-9][0-9]_[bar|dog|cat]"
or
NAME="FOO[0-9][0-9]_'bar|dog|cat'"

ただし、正規表現に関するドキュメントでは正確な一致に関する内容が見つかりません。

私が使用する基本スクリプトははるかに複雑で、さまざまなサブプロセスがかかっているので、1行に入力する必要があります。

これはまだ可能です…?

答え1

文字列一致のみを使用するには、次のものを使用する必要があります=~(拡張正規表現一致とともに):

if [[ "${FILENAME}" =~ "FOO[0-9][0-9]_(bar|dog|cat)" ]]

または

NAME="FOO[0-9][0-9]_(bar|dog|cat)"
if [[ "${FILENAME}" =~ ${NAME} ]]

元のバージョンと一致するようにします。

==常にワイルドカードの一致(またはワイルドカードが無効になっている場合は正確な一致)であり、正規表現では使用できません。

または、GNUを使用すると想定してスクリプトをさらに変更できる場合は、次のようにfindフィルタリングできますfind

find ${DIR} -maxdepth 1 -type f -regextype posix-extended -regex ".*/FOO[0-9][0-9]_(bar|dog|cat)\.[Dd][Oo][Cc]"

(拡張正規表現を使用するように-regextype posix-extended指示すると、find正規表現自体はファイル名だけでなくフルパスと一致する.*/ためで始まります。)-regex

答え2

出力を繰り返さないでくださいfindfindただし、パス名を使用して指定したスクリプトを実行するために使用されます。

#!/bin/bash

topdir='/search/path'
pattern='FOO[0-9][0-9]_(bar|dog|cat)'

find "$topdir" -type f -maxdepth 1 -iname '*.doc' -exec bash -c '
    pattern=$1; shift
    for pathname do
        stem=$( basename "${pathname%.*}" )
        if [[ "$stem" =~ $pattern ]]; then
            printf "Found %s\n" "$pathname"
        else
            printf "No match in %s\n" "$pathname"
        fi
    done' bash "$pattern" {} +

-inamewithを使用すると、findファイル名の大文字と小文字が区別されません。

関連:

または、より簡単に以下を使用してくださいbash

#!/bin/bash

topdir='/search/path'
pattern='FOO[0-9][0-9]_(bar|dog|cat)'

shopt -s globstar nullglob

for pathname in "$topdir"/**/*.[Dd][Oo][Cc]; do
    stem=$( basename "${pathname%.*}" )
    if [[ "$stem" =~ $pattern ]]; then
        printf "Found %s\n" "$pathname"
    else
        printf "No match in %s\n" "$pathname"
    fi
done

または、次のファイル名全体にワイルドカードを使用します。

#!/bin/bash

topdir='/search/path'

shopt -s globstar nullglob extglob

for pathname in "$topdir"/**/*FOO[0-9][0-9]_@(bar|dog|cat)*.[Dd][Oo][Cc]
do
    printf "Found %s\n" "$pathname"
done
  • globstar**同様に機能しますが、パス名のスラッシュと一致するglobモードを有効にします*
  • nullglob一致しないグローバルパターンが空の文字列に展開されます。
  • extglobいくつかの拡張グローバルモードを提供します。@(...)括弧内のパターンの1つと一致します。

1行の場合は、次のものを使用できます。

shopt -s globstar nullglob extglob; printf 'Found %s\n' "$topdir"/**/*FOO[0-9][0-9]_@(bar|dog|cat)*.[Dd][Oo][Cc]

ただし、一致するものがない場合は、文字列をFound1行に印刷します。

関連情報