명령 줄 mv 제외 목록 file3, 나는 이동하려는 file1및 file2곳. 이동할 파일의

방법에 있는가 mv, cp또는 내가 모든 파일을 지정할 수 있도록 모든 파일 작업을 하지 않는 영향을 원하는가?

예를 들어, 나는 파일이있는 폴더가 있다고 가정 해 file1, file2그리고 file3, 나는 이동하려는 file1file2곳. 이동할 파일의 이름을 명시 적으로 지정하는 대신 ( mv file1 file2 /path/to/destination) 이동 하지 않을 파일의 이름을 지정 하고 폴더의 다른 모든 파일 을 이동 시키려고합니다 ( mv --some-switch file3 /path/to/destination)



답변

  • 일부 셸에서 고급 글 로빙 패턴을 사용하여 특정 패턴과 일치하는 파일을 제외하고 디렉토리의 모든 파일을 일치시킬 수 있습니다. 예를 들어 ksh, bash 또는 zsh에서

    shopt -s extglob   ## needed in bash only
    setopt ksh_glob   ## needed in zsh only
    mv /source/!(*.bak) /destination
    

    일치하는 파일 /source/destination제외한 모든 파일을 이동합니다 *.bak. zsh에서는 /source/^*.bak처음 실행 setopt extended_glob하고 더 일반적으로 (다시 요구해야 함 setopt extended_glob) /source/*~*.bak(또는 /source/a*~*.bak파일을 a제외하고 이름이 시작하는 모든 파일에 대해 ) 쓸 수도 있습니다 .bak.

  • Zsh에는 패턴과 일치하는 파일을 제외한 모든 파일을 이동하는 데 사용할 수있는 대량 복사 / 이동 / 링크 명령이 있습니다. 예를 들어 다음 명령은 *.bakfrom /source을 제외한 모든 파일을 이동 하고 프로세스에서 해당 파일 이름에 target추가 .bak합니다.

    autoload zmv
    zmv '/source/(*)~*.bak' '/target/$1.bak'
    
  • rename플로팅 이라는 몇 가지 명령이 있습니다 . 데비안과 우분투에서 /usr/bin/rename펄 스크립트는 파일을 펄 표현식에 의해 생성 된 새로운 이름으로 옮기는 펄 스크립트입니다. 파일을 제외 할 경우 새 이름을 생성하지 않으면 파일 이름 바꾸기에서 제외 할 수 있습니다. 예를 들어 다음 명령 (이 특정 rename프로그램 사용)은 *.bak에서 /source를 제외한 모든 파일 을 /target다음으로 이동합니다 .

    rename 's!/source!/target! unless m!\.bak$!' /source/*
    
  • find명령을 사용하여 이동할 파일을 선택할 수 있습니다 . 예를 들어 다음 명령은 *.bakin /source또는 하위 디렉토리를 제외한 모든 일반 파일을 디렉토리로 이동합니다 /target(디렉토리 구조가 축소됨).

    find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
    

    또는 (이동할 파일이 많은 경우 더 효율적)

    find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
    
  • rsync의 일반화 cpscp매우 강력한 / 포함 규칙을 제외와 함께. 예를 들어, 다음 명령 은 디렉토리 구조 와 관련하여 *.bakin /source또는 서브 디렉토리를 제외한 모든 파일을로 복사합니다 /target.

    rsync -a --exclude '*.bak' /source/ /target/
    
  • paxcp스테로이드의 다른 것 입니다. 제외 규칙은 rsync만큼 강력하지는 않지만 파일을 복사 할 때 이름을 바꿀 수있는 추가 기능이 있습니다. 파일 이름을 빈 문자열로 바꾸면 복사본에서 제외됩니다. 예를 들어, 다음 명령 *.bak은 in /source또는 서브 디렉토리를 제외한 모든 파일을로 복사하고 전달시 /target파일 이름을 바꿉니다 .bak.

    cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
    

    위의 예는 다음 과 foo.bak결합 find하여 피할 수있는 이라는 디렉토리를 만들면 불행한 부작용 이 있습니다 pax.

    { cd /source && find . -type f; } | \
    pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/