숫자가 포함된 파일 이름 찾기

숫자가 포함된 파일 이름 찾기

숫자가 포함된 파일 이름을 찾아 숫자 범위에 나열하고 싶습니다. 예를 들어, 내 디렉토리에는 다음이 있습니다. **

Ion_001_rawlib.bam
Ion_002_rawlib.bam
Ion_003_rawlib.bam
Ion_004_rawlib.bam
Ion_005_rawlib.bam
...
Ion_020_rawlib.bam

**

003부터 005까지 Ion 파일 이름만 나열하고 싶습니다. 나는 이것을 시도한다:

find -name '*Ion_*[3-5]*rawlib.bam'

하지만 원하는 효과를 얻지는 못했습니다. 이것이 가능한지 알고 계십니까? 감사해요.

답변1

zsh셸을 사용하면 다음을 수행할 수 있습니다.

print -rC1 Ion_<3-5>_rawlib.bam

<x-y>여기서는 주어진 범위(~부터 포함) 내에서 양의 정수의 리터럴 십진수 표현 과 일치하는 전역 연산자입니다 .xy

재귀적으로:

print -rC1 -- **/Ion_<3-5>_rawlib.bam

( (D)숨겨진 폴더에서도 이러한 파일을 찾고 싶거나, 일치하는 파일이 없을 때 오류로 처리되지 않도록 하려면 (N)추가하세요 .)

find조건자를 지원하는 구현을 사용하면 -regex다음을 수행할 수 있습니다.

LC_ALL=C find . -regex '.*/Ion_0*[345]_rawlib\.bam'

*(0개 이상의 ( ) 바이트( .with LC_ALL=C), 그 뒤에 /Ion_0개 이상의 ( *) 0, 또는 문자 중 하나, 뒤에 3오는 파일 경로와 일치합니다 .)45rawlib.bam

여기서는 3..5 범위의 경우 상대적으로 쉽지만 78..123과 같은 범위의 경우 더 고통스럽습니다(그리고 다른 형식을 사용하는 정규식이 find지원되므로-regex

표준은 정규 표현식 대신 기본 쉘 와일드카드를 사용하여 수행되는 파일 이름 일치 및 일치만을 find지원 하지만 와일드카드에는 정규 표현식 연산자(0개 이상의 선행 원자)와 동일한 연산자가 없으며 해당 연산자는 정규 표현식 (0개 이상의 문자) 과 동일합니다 . , 예를 들어 match on 과 일치 합니다 .-name-path**.*Ion_*[3-5]_rawlib.bamIon_9994_rawlib.bam*999

그러나 이 간단한 경우에는 다양한 패턴과 부정을 사용하여 이를 수행할 수 있습니다. 예를 들면 다음과 같습니다.

LC_ALL=C find . -name 'Ion_*[345]_rawlib.bam' \
              ! -name 'Ion_*[!0]*?_rawlib.bam'

비재귀적:

LC_ALL=C find . ! -name . -prune \
    -name 'Ion_*[345]_rawlib.bam' \
  ! -name 'Ion_*[!0]*?_rawlib.bam'

이름에 정수 십진 표현이 포함된 파일을 찾으려면 x해당 범위와 일치하는 패턴(예: s )이 필요하지만 패턴이 다른 숫자로 둘러싸여 있지 않은지 확인해야 합니다. 예를 들어 , 및 가 포함되어 있으며 모두 일치합니다.yzsh<x-y>foo305.txt3055<3-5>

에서는 zsh다음과 같습니다.

print -rC1 -- (|*[^0-9])<3-5>(|[^0-9]*)

<3-5>, (3, 03, 003...과 일치) 뒤에 숫자가 아닌 것으로 끝나는 문자열이나 문자열이 오고, 숫자가 아닌 것으로 시작하는 문자열이나 문자열이 옵니다.

BSD 사용 find:

LC_ALL=C find -E . -regex '.*/([^/]*[^0-9])?0*[3-5]([^0-9][^/]*)?'

GNU 와 동일 find하지만 .-E .. -regextype posix-extended

busybox 사용 find(컴파일 방법에 따라 다름):

busybox find . -regex '.*/\([^/]*[^0-9]\)\?0*[3-5]\([^0-9][^/]*\)\?'

find또 다른 접근 방식은 보고서 파일 목록을 사용하는 것이지만 perl목록 필터링과 같은 더 높은 수준의 언어를 사용하는 것입니다.

find . -print0 | perl -l -0ne '
  if (m{[^/]*\z}) {
    for $n ($& =~ /\d+/g) {
      if ($n >= 3 && $n <= 5) {
        print;
        next LINE;
      }
    }
  }'

perl여기서는 각 파일의 기본 이름에서 모든 십진수 시퀀스를 추출하고 이러한 숫자 시퀀스 중 하나 이상이 3..5 범위의 숫자를 나타내는 경우 파일을 출력하는 데 사용됩니다 .

관련 정보