이름에 숫자 20~32가 포함된 파일을 복사하는 방법

이름에 숫자 20~32가 포함된 파일을 복사하는 방법

copyDest에서 PastDest로 20부터 32까지의 숫자가 포함된 파일을 복사하고 싶습니다. 내가 뭘 잘못했나요?

cp -r ~/copyDest/*2[0-9]|3[0-2]* ~/pasteDest

감사해요.

답변1

|파이프라인 운영자입니다.

cp -r ~/copyDest/*2[0-9]|3[0-2]* ~/pasteDest

glob에서 확장된 첫 번째 파일이라는 명령 cp에 파이프된 명령 입니다 . 전역 대체 연산자가 3[0-2]*되려면 in (단, 숫자 범위 일치를 위한 전용 연산자 포함) 및 in (또는 with on)이 |있어야 합니다 .(...)zshzsh@(...)kshbashextglob

따라서 zsh:

cp -r ~/copyDest/(*[^0-9]|)<20-32>(|[^0-9]*) ~/pasteDest

그렇지 않은 경우 (*[^0-9]|)foo120과도 일치합니다.

kshor (또는 inside ) 또는 (within) 을 사용하면 bash -O extglob해당 항목(파일이 복사되는 순서를 제외하고)은 다음과 같습니다.shopt -s extglobbashzsh -o kshglobset -o kshglobzsh

(
  LC_ALL=C
  cp -r ~/copyDest/?(*[^0-9])*(0)@(2[0-9]|3[0-2])?([^0-9]*) ~/pasteDest
)

ksh 또는 bash의 경우 대부분의 시스템과 C를 제외한 대부분의 로케일에서 [0-9]0123456789보다 더 많은 문자가 일치하므로 LC_ALL=C(이는 glob 확장 정렬 순서에도 영향을 미칩니다) 파일 이름에 ASCII 문자만 포함된 경우 이를 생략할 수 있습니다. 일반 시스템의 로케일에는 0123456789 이외의 ASCII 문자가 포함될 것이라고 생각하지 않기 때문입니다 [0-9]. 다른 대안은 [0-9]로 대체하는 것입니다 [0123456789].

또한 zsh -o kshglob패턴이 in 이외의 파일과 일치하지 않으면 cp리터럴 인수(유효하지만 있을 가능성이 없는 파일 이름)를 사용하여 호출되며 .../?(*[^0-9])*(0)@(2[0-9]|3[0-2])?([^0-9]*), 존재하는 경우 복사됩니다( cp그렇지 않으면 실수로 반환됨). 에서는 bashfailglob옵션을 사용하여 보다 정상적인 동작에 더 가까워질 수 있습니다 zsh(패턴이 일치하지 않으면 명령을 취소).

foo20.txt위에서 우리는 이름이 인 파일을 복사하는 데 특별한 주의를 기울였습니다 . foo00020.txt그러나 이름이 foo120.txt또는 인 파일은 복사하지 않았습니다 foo200.txt(이름에 20이 포함된 경우에도). 여전히 foo32.12.txt또는 foo-1E-20.txt또는 파일을 복사합니다 foo0x20.txt.

foo120여전히 복사 하거나 파일로 보관하려는 경우 foo200훨씬 더 간단해집니다.

  • zsh:

    cp -r ~/copyDest/*<20-32>* ~/pasteDest
    
  • bash -O extglob협력:

    cp -r ~/copyDest/*@(2[0123456789]|3[012])* ~/pasteDest
    

답변2

쉘 패턴 일치에 대한 매뉴얼을 읽지 않았고 그것이 일반적으로 "정규 표현식"이라고 불리는 것과 동일하다고 가정했습니다. 예제에서 사용한 연산자의 의미가 다르다는 사실은 *그 연산자가 다르다는 것을 의미합니다.

Bash(및 기타 일부 쉘)의 경우 {,}연산자를 사용하여 원하는 효과를 얻을 수 있습니다.

cp -r ~/copyDest/*{2[0-9],3[0-2]}* ~/pasteDest

그러나 차이점이 있다는 점에 유의하세요. 글쓰는거랑 똑같네

cp -r ~/copyDest/*2[0-9]* ~/copyDest/*3[0-2]* ~/pasteDest

즉, 두 패턴 중 어느 파일과도 일치하지 않으면 인수로 전달되고 cp파일 cp이 존재하지 않는다고 불평합니다. nullglob이러한 상황을 방지하려면 셸 옵션을 설정할 수 있습니다 .

답변3

bash방법. 보너스로, 일치하는 파일이 발견되지 않은 번호를 인쇄합니다.

[steve@instance-2 ~]$ find copyDest pasteDest
copyDest
copyDest/file15
copyDest/file20
copyDest/file25
copyDest/file32
copyDest/file33
pasteDest
[steve@instance-2 ~]$ cp -pr ~/copyDest/*{20..32}* pasteDest
cp: cannot stat ‘/home/steve/copyDest/*21*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*22*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*23*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*24*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*26*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*27*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*28*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*29*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*30*’: No such file or directory
cp: cannot stat ‘/home/steve/copyDest/*31*’: No such file or directory
[steve@instance-2 ~]$ find copyDest pasteDest
copyDest
copyDest/file15
copyDest/file20
copyDest/file25
copyDest/file32
copyDest/file33
pasteDest
pasteDest/file20
pasteDest/file25
pasteDest/file32
[steve@instance-2 ~]$

답변4

정규식 일치가 아닌 패턴 일치를 수행해야 합니다. 쉘의 매뉴얼 페이지를 확인하십시오. 다음과 같은 것을 시도해보세요

ls  *2[0-9]* *3[0-2]*

즉, 두 가지 모드를 제공함으로써 교번이 이루어진다.

관련 정보