파일 이름을 정규식과 일치시키는 줄?

파일 이름을 정규식과 일치시키는 줄?

작은 스크립트가 있습니다.

#!/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

문자열 일치만 사용하려면 다음을 사용해야 합니다 =~(확장 정규식 일치와 함께):

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일부 확장된 전역 모드를 제공합니다. @(...)괄호 안의 패턴 중 하나와 일치합니다 .

한 줄의 경우 다음을 사용할 수 있습니다.

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

그러나 일치하는 항목이 없으면 여전히 문자열을 Found한 줄에 인쇄합니다.

관련 정보