파일 이름 범위를 기준으로 파일을 찾는 방법은 무엇입니까?

파일 이름 범위를 기준으로 파일을 찾는 방법은 무엇입니까?

2341a.po, 등의 4567211someword.po숫자 이름을 가진 파일이 있습니다. 0012.po숫자 범위를 기반으로 파일 세트를 찾고 싶습니다. 예를 들어 [126 - 363].

보통 저는 정규 표현식을 사용합니다 find. 모든 숫자 범위는 두 개의 정규 표현식과 로 구성될 수 있습니다 [N, M].larger than Nless than M

N보다 큼:

그렇다면 먼저 모든 사람에게 N = vxyz일치합니다 .value > V000, (V=v+1)[V-9]\d{3,}

그런 다음 vX00, X=x+1, 및v[X-9]\d\d

그런 다음 vxY0, Y=y+1, 및vx[Y-9]\d

마침내vxy[z-9]

예:

일치시키기 위해 number>=234다음을 사용합니다.

`^(0*([3-9]\d{2,}|2[4-9]\d|23[4-9]))`

M 미만:

비슷한 논리를 바탕으로 다음과 같은 결과를 얻을 수 있습니다.

^(0*(vxy[0-z]|vx[0-Y]\d|v[0-X]\d\d|[1-V]\d\d|\d{1,3}))[^0-9]

그리고Y=y-1,X=x-1,V=v-1

예를 들어, 다음 명령은 [253, 326] 사이의 모든 파일을 찾습니다.

find . -maxdepth 1 -type f -regextype posix-extended -iregex '^\./0*([3-9][0-9]{2,}|2[6-9][0-9]{2,}|25[3-9]).*' -iregex '^\./0*(32[0-6]|3[0-1][0-9]|[0-2][0-9][0-9]|[0-9]{1,2})[^0-9].*'

그러나 이 접근 방식은 긴 숫자를 처리하기에는 너무 짜증스럽습니다. 이 작업을 수행하는 더 좋고 쉬운 방법이 있습니까?

답변1

그리고 zsh:

setopt extendedglob # best in ~/.zshrc
ls -ld -- <126-253>(*.po~[0-9]*)

즉, 10진수 126~253(000126도 허용됨), 그 뒤에 .po10진수로 끝나고 10진수로 시작하지 않는 숫자가 옵니다.

숨겨진 디렉터리와 일반 파일만 포함하여 재귀적으로:

ls -ld -- **/<126-253>(*.po~[0-9]*)(D.)

당신 zargs이 만난다면arg list too long실수.

리터럴 숫자 대신 변수를 사용하려면 이 작업을 수행할 수 없습니다 <$low-$high>. 이 <x-y>연산자는 리디렉션 연산자( echo <3-4> zPOSIX 셸에서는 파일 echo에서 3-리디렉션된 입력 으로 실행하고 fd 4 로 입력 z) 와 겹쳐서 zsh리터럴 숫자만 허용하여 충돌 위험을 최소화하려고 합니다. 그러나 이 연산자를 globsubsting 확장의 일부로 사용할 수 있습니다 . 예를 들면 다음과 같습니다.

low=126 high=253
ls -ld -- ${~:-"<$low-$high>"}(*.po~[0-9]*)

활성화됨 ${~expansion}( globsubst확장에 와일드카드 사용 허용)은 확장을 무엇이든 확장할 수 있도록 허용하는 특수 형식 expansion입니다 .${:-"text"}${var:-default}text

답변2

찾으려는 숫자가 포함된 파일 목록을 생성하고 이를 매개변수 목록에 넣어 find사용할 수 있습니다 xargs. 예를 들어, 질문에서와 같이 사용하는 것과 동일한 것은 다음 과 같습니다 bash.-maxdepth 1

echo {253..326} | xargs sh -c 'find "$@" -type f -maxdepth 0' sh

-I옵션 xargs(예: xargs -I{} find {} -type f) 을 사용할 수 있지만 GNU는 이 옵션을 xargs강제합니다 -L 1. 즉, 각 인수에 대해 별도의 조회 프로세스를 시작한다는 의미입니다. 사용하면 sh이 문제를 해결할 수 있습니다.

어떤 깊이에서도 다음을 수행할 수 있습니다.

printf -- '-o -name %d ' {254..326} |
  xargs -n 3000 sh -c 'find -type f \( -name 253 "$@" \)' sh

매개변수 -n(명령당 추가되는 최대 매개변수 수)는 매개변수 목록 구조의 크기가 제한되도록 선택해야 합니다 xargs. 너무 크면 매개변수 개수보다는 매개변수 목록의 전체 크기로 인해 한계에 도달할 수 있습니다. -o목록에 뒤에 오는 or가 남지 않도록 3의 배수여야 합니다 .-name

답변3

Graeme의 답변에 대한 강력한 확장 :

find . -type f -regextype posix-awk -regex ".*/0*($(seq -s'|' 254 456)).*" 

POSIX가 필요한 경우 \|대신 사용할 수 |있습니다 (하지만 POSIX는 아니죠?).\(\)()seq

$ find . -maxdepth 2 -type f -regextype posix-awk -regex ".*/0*($(seq -s'|' 254 456)).*"    
./.fontconfig/3047814df9a2f067bd2d96a2b9c36e5a-le32d4.cache-3
./.fontconfig/3830d5c3ddfd5cd38a049b759396e72e-le32d4.cache-3
./.fontconfig/385c0604a188198f04d133e54aba7fe7-le32d4.cache-3
./Documents/374620-63301.pdf
./4567211someword.po

잘. 숫자 끝을 표시하려면 숫자가 아닌 문자를 추가해야 할 것 같습니다. 아마도 ".*/0*($(seq -s'|' 254 456))[^0-9].*"?

답변4

find | perl -ne 'print if(m!^\./(\d+)! and $1 > 126 and $1 <363)'

...다른 답변에서 제안된 좋은 아이디어를 추가할 수도 있습니다.

정규 표현식에 약간의 조정이 필요할 수 있습니다(예 ^\./(\d+)\w*.po$: :)

관련 정보