어떻게 사용할 수 있습니 반전 또는 부정적인 때 와일드카드는 패턴 매칭에서 unix/linux 니까?

StackOverflow https://stackoverflow.com/questions/216995

문제

말 복사하려는 디렉토리 내용을 제외하고 파일 및 폴더가 이름에 포함된 단어는'음악'.

cp [exclude-matches] *Music* /target_directory

어떻게 가야하는 장소에서의[제외-일치]to accomplish this?

도움이 되었습니까?

해결책

Bash에서는 활성화하여 수행 할 수 있습니다 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 Shell 옵션이 활성화되면 여러 확장 패턴 매칭 연산자가 인식됩니다. 다음 설명에서, Pat Tern-List는 | |로 분리 된 하나 이상의 패턴의 목록입니다. 복합 패턴은 하나 이상의 다음 하위 패턴을 사용하여 형성 될 수 있습니다.

  • ? (패턴 목록)
    주어진 패턴의 0 또는 한 번의 발생과 일치합니다
  • *(패턴 목록)
    주어진 패턴의 0 이상 발생과 일치합니다
  • +(패턴 목록)
    주어진 패턴의 하나 이상의 발생과 일치합니다
  • @(패턴 목록)
    주어진 패턴 중 하나와 일치합니다
  • ! (패턴 목록)
    주어진 패턴 중 하나를 제외한 모든 것이 일치합니다

예를 들어, 현재 디렉토리에 모든 파일을 나열하려는 경우 .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 extglob 입니다 GLOBIGNORE 변하기 쉬운. 더 나은 것은 아니지만 기억하기가 더 쉽습니다.

원래 포스터가 원하는 예일 수 있습니다.

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 명령을 사용하는 것입니다. 이를 통해 강력하지만 읽을 수있는 스크립트를 작성하여 원하는 것을 정확하게 수행하게됩니다. 또한 Echo 명령을 사용하면 실제 작업을 수행하기 전에 드라이 런을 수행 할 수 있습니다. 예를 들어:

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

복사 할 파일을 인쇄합니다. 목록이 올바른 경우 다음 단계는 Echo 명령을 다음과 같이 복사 명령으로 간단히 바꾸는 것입니다.

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

중 하나 이것에 대한 솔루션을 찾을 수 있습니다 찾을 수 있습니다.

$ mkdir foo bar
$ touch foo/a.txt foo/Music.txt
$ find foo -type f ! -name '*Music*' -exec cp {} bar \;
$ ls bar
a.txt

찾기가 매우 몇 가지 옵션이,당신이 얻을 수있는 아주 특정에서 무엇을 포함 및 제외합니다.

편집:아담에서 의견 주목하는 이는 재귀적입니다.옵션을 찾을 수 있 mindepth 및 maxdepth 에 유용할 수 있습니다했습니다.

트릭을 나는 보지 못했 여기에는 아직 사용하지 않는 extglob, find, 나 grep 가를 치료하는 두 개의 파일 목록을 세 "차이" 을 사용하여 그들을 comm:

comm -23 <(ls) <(ls *Music*)

comm 이 바람직 diff 이 없기 때문에 추가 크.

이를 반환 모든 요소의 설정 1, ls, 는 에서도 설정 2, ls *Music*.이 모두 필요합 세트에 있을 정렬하기 위해 제대로 작동합니다.에 대한 문제가 없 ls 고 glob 확장,하지만 경우에 당신은 같은 것을 사용하는 find, 해야 호출 sort.

comm -23 <(find . | sort) <(find . | grep -i '.jpg' | sort)

잠재적으로 유용합니다.

다음 작품은 모두 나열됩니다 *.txt 숫자로 시작하는 파일을 제외하고는 현재 DIR의 파일입니다.

이것은 작동합니다 bash, dash, zsh 그리고 다른 모든 posix 호환 쉘.

for FILE in /some/dir/*.txt; do    # for each *.txt file
    case "${FILE##*/}" in          #   if file basename...
        [0-9]*) continue ;;        #   starts with digit: skip
    esac
    ## otherwise, do stuff with $FILE here
done
  1. 라인에서 패턴 /some/dir/*.txt 원인이 될 것입니다 for 루프는 모든 파일을 반복합니다 /some/dir 누구의 이름이 끝나고 끝납니다 .txt.

  2. 두 줄에서는 사례 명세서가 사용되지 않은 파일을 제거하는 데 사용됩니다. - ${FILE##*/} 표정 /some/dir/) 따라서 Patters는 파일의베이스 이름에만 일치 할 수 있습니다. (접미사를 기반으로 파일 이름을 잡초화하는 경우 $FILE 대신에.)

  3. 3 행에서는 모든 파일이 일치합니다 case 무늬 [0-9]*) 라인이 건너 뜁니다 ( continue 진술은 다음 반복으로 점프합니다 for 고리). - 당신이 원하는 경우 여기서 더 흥미로운 일을 할 수 있습니다. [!a-z]*, 또는 여러 패턴을 사용하여 여러 종류의 파일 이름을 건너 뛸 수 있습니다. [0-9]*|*.bak 둘 다 파일을 건너 뜁니다 .bak 숫자로 시작하지 않는 파일 및 파일.

이것은 정확히 '음악'을 제외 할 것입니다.

cp -a ^'Music' /target

이것은 음악과 같은 것을 제외하고? * 또는 *? 음악

cp -a ^\*?'complete' /target
cp -a ^'complete'?\* /target
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top