작은 스크립트가 있습니다.
#!/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
문자열 일치만 사용하려면 다음을 사용해야 합니다 =~
(확장 정규식 일치와 함께):
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
일부 확장된 전역 모드를 제공합니다.@(...)
괄호 안의 패턴 중 하나와 일치합니다 .
한 줄의 경우 다음을 사용할 수 있습니다.
shopt -s globstar nullglob extglob; printf 'Found %s\n' "$topdir"/**/*FOO[0-9][0-9]_@(bar|dog|cat)*.[Dd][Oo][Cc]
그러나 일치하는 항목이 없으면 여전히 문자열을 Found
한 줄에 인쇄합니다.