
小さなスクリプトがあります。
#!/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]_
で始まるすべてのファイルを一致させようとします。しかし、またはなどの他のものがある場合は、bar
dog
cat
bog
cog
car
いいえマッチ。
これは[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
出力を繰り返さないでくださいfind
find
ただし、パス名を使用して指定したスクリプトを実行するために使用されます。
#!/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" {} +
-iname
withを使用すると、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]
ただし、一致するものがない場合は、文字列をFound
1行に印刷します。