[bash] 유닉스 / 리눅스 쉘에서 패턴 일치시 역 또는 음의 와일드 카드를 어떻게 사용할 수 있습니까?

이름에 ‘Music’이라는 단어가 포함 된 파일과 폴더를 제외한 디렉토리의 내용을 복사하려고한다고 가정 해 봅시다.

cp [exclude-matches] *Music* /target_directory

이를 수행하기 위해 [제외 일치] 대신 무엇을해야합니까?



답변

배쉬에서 당신이 가능하게하여 그것을 할 수있는 extglob다음과 같은 옵션을 (교체 ls와 함께 cp물론, 대상 디렉토리를 추가)

~/foobar> shopt extglob
extglob        off
~/foobar> ls
abar  afoo  bbar  bfoo
~/foobar> ls !(b*)
-bash: !: event not found
~/foobar> shopt -s extglob  # Enables extglob
~/foobar> ls !(b*)
abar  afoo
~/foobar> ls !(a*)
bbar  bfoo
~/foobar> ls !(*foo)
abar  bbar

나중에 extglob을 비활성화 할 수 있습니다

shopt -u extglob


답변

extglob쉘 옵션은 당신에게 명령 줄에서 더 강력한 패턴 매칭을 제공합니다.

당신은에 그것을 설정 shopt -s extglob하고 그것을 해제 shopt -u extglob.

귀하의 예에서는 처음에 다음을 수행합니다.

$ shopt -s extglob
$ cp !(*Music*) /target_directory

전체 사용 가능한 내선는 종료 글로브의 빙 사업자 (발췌입니다 man bash) :

shopt 내장을 사용하여 extglob 쉘 옵션을 사용하면 여러 확장 패턴 일치 연산자가 인식됩니다. 패턴 목록은 |으로 구분 된 하나 이상의 패턴 목록입니다. 복합 패턴은 다음 하위 패턴 중 하나 이상을 사용하여 형성 될 수 있습니다.

  • ? (pattern-list)
    주어진 패턴이 0 번 또는 1 번 일치합니다.
  • * (pattern-list)
    0 개 이상의 주어진 패턴과 일치
  • + (pattern-list)
    주어진 패턴 중 하나 이상을 찾습니다
  • @ (pattern-list)
    주어진 패턴 중 하나와 일치
  • ! (pattern-list)
    주어진 패턴 중 하나를 제외한 모든 것과 일치

당신이없는 현재 디렉토리에있는 모든 파일 목록을하고 싶어한다면, 예를 들어, .c또는 .h파일을, 당신은 할 것이다 :

$ ls -d !(*@(.c|.h))

물론 일반적인 쉘 글 로빙이 작동하므로 마지막 예제는 다음과 같이 쓸 수도 있습니다.

$ ls -d !(*.[ch])


답변

bash에는 없지만 (내가 아는) :

cp `ls | grep -v Music` /target_directory

나는 이것이 당신이 찾고있는 것이 아니라는 것을 알고 있지만, 당신의 모범을 해결할 것입니다.


답변

exec 명령을 사용하여 mem 비용을 피하려면 xargs로 더 잘 할 수 있다고 생각합니다. 다음은 더 효율적인 대안이라고 생각합니다.

find foo -type f ! -name '*Music*' -exec cp {} bar \; # new proc for each exec



find . -maxdepth 1 -name '*Music*' -prune -o -print0 | xargs -0 -i cp {} dest/


답변

bash에서 대안 shopt -s extglobGLOBIGNORE변수 입니다. 실제로는 좋지 않지만 기억하기가 더 쉽습니다.

원래 포스터가 원하는 것일 수있는 예 :

GLOBIGNORE="*techno*"; cp *Music* /only_good_music/

완료되면 소스 디렉토리에 unset GLOBIGNORE있을 수 있습니다 rm *techno*.


답변

꽤 간단한 for루프를 사용할 수도 있습니다 .

for f in `find . -not -name "*Music*"`
do
    cp $f /target/dir
done


답변

개인적으로 선호하는 것은 grep과 while 명령을 사용하는 것입니다. 이를 통해 강력하면서도 읽기 쉬운 스크립트를 작성하여 원하는대로 정확하게 작업 할 수 있습니다. 또한 에코 명령을 사용하면 실제 작업을 수행하기 전에 드라 이런을 수행 할 수 있습니다. 예를 들면 다음과 같습니다.

ls | grep -v "Music" | while read filename
do
echo $filename
done

복사 할 파일을 인쇄합니다. 리스트가 올 바르면 다음 단계는 단순히 echo 명령을 다음과 같이 copy 명령으로 바꾸는 것입니다.

ls | grep -v "Music" | while read filename
do
cp "$filename" /target_directory
done