숫자가 포함된 파일 이름을 찾아 숫자 범위에 나열하고 싶습니다. 예를 들어, 내 디렉토리에는 다음이 있습니다. **
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>
여기서는 주어진 범위(~부터 포함) 내에서 양의 정수의 리터럴 십진수 표현 과 일치하는 전역 연산자입니다 .x
y
재귀적으로:
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
오는 파일 경로와 일치합니다 .)4
5
rawlib.bam
여기서는 3..5 범위의 경우 상대적으로 쉽지만 78..123과 같은 범위의 경우 더 고통스럽습니다(그리고 다른 형식을 사용하는 정규식이 find
지원되므로-regex
표준은 정규 표현식 대신 기본 쉘 와일드카드를 사용하여 수행되는 파일 이름 일치 및 일치만을 find
지원 하지만 와일드카드에는 정규 표현식 연산자(0개 이상의 선행 원자)와 동일한 연산자가 없으며 해당 연산자는 정규 표현식 (0개 이상의 문자) 과 동일합니다 . , 예를 들어 match on 과 일치 합니다 .-name
-path
*
*
.*
Ion_*[3-5]_rawlib.bam
Ion_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 )이 필요하지만 패턴이 다른 숫자로 둘러싸여 있지 않은지 확인해야 합니다. 예를 들어 , 및 가 포함되어 있으며 모두 일치합니다.y
zsh
<x-y>
foo305.txt
3
05
5
<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 범위의 숫자를 나타내는 경우 파일을 출력하는 데 사용됩니다 .