it-swarm-ko.tech

Rsync 필터 : 하나의 패턴 만 복사

LaTeX에서 컴파일 한 PDF 만 모두 저장할 디렉토리를 만들려고합니다. 각 프로젝트를 LaTeX라는 큰 폴더에있는 별도의 폴더에 보관하는 것이 좋습니다. 그래서 나는 달리기를 시도했다.

rsync -avn *.pdf ~/LaTeX/ ~/Output/

~/LaTeX/에서 모든 pdf를 찾아 출력 폴더로 전송해야합니다. 작동하지 않습니다. "*.pdf"와 일치하는 항목이 없다는 것을 알려줍니다. 이 필터를 생략하면 명령은 LaTeX 아래의 모든 프로젝트 폴더에있는 모든 파일을 나열합니다. 따라서 * .pdf 필터에 문제가 있습니다. ~/를 내 홈 디렉토리의 전체 경로로 바꾸려고했지만 아무런 영향을 미치지 않았습니다.

Zsh를 사용하고 있습니다. bash에서 동일한 작업을 시도했지만 모든 하위 디렉토리의 모든 단일 파일을 나열한 필터 with 필터를 시도했습니다.

Rsync가 내 PDF 전용 필터를 이해하지 못하는 이유는 무엇입니까?


확인. 그래서 업데이트 : 아니오 노력하고 있습니다.

rsync -avn --include="*/" --include="*.pdf" LaTeX/ Output/

그리고 이것은 전체 파일 목록을 제공합니다. 모든 것이 첫 번째 패턴과 일치하기 때문에 ...

142
Seamus

TL, DR :

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

Rsync는 소스를 대상으로 복사합니다. *.pdf를 소스로 전달하면 셸은 현재 디렉토리에서 확장자가 .pdf 인 파일 목록으로 확장합니다. 디렉토리를 소스로 전달하지 않았기 때문에 재귀 순회가 발생하지 않습니다.

따라서 rsync -a ~/LaTeX/ ~/Output/를 실행해야하지만 rsync에게 .pdf 파일 만 복사하도록하는 필터를 사용해야합니다. 매뉴얼을 읽으면 Rsync의 필터 규칙이 어려워 보일 수 있지만 몇 가지 간단한 규칙으로 많은 예제를 구성 할 수 있습니다.

  • 포함 및 제외 :

    • 이름 또는 위치별로 파일을 쉽게 제외 할 수 있습니다 : --exclude=*~, --exclude=/some/relative/location (예 : 소스 인수와 관련하여 ~/LaTeX/some/relative/location 제외).
    • 몇 개의 파일 또는 위치 만 일치 시키려면 그것으로 이어지는 모든 디렉토리 포함 (예 : --include=*/)를 포함하고 나머지는 --exclude='*'. 이 때문입니다:
    • 디렉토리를 제외하면 디렉토리 아래의 모든 것이 제외됩니다. 제외 된 파일은 전혀 고려되지 않습니다.
    • 디렉토리를 포함하면 디렉토리 내용이 자동으로 포함되지 않습니다. 최신 버전에서는 --include='directory/***'가 그렇게합니다.
    • 각 파일에 대해 첫 번째 일치 규칙이 적용되며 일치하지 않는 항목이 포함됩니다.
  • 패턴 :

    • 패턴에 /가 포함되어 있지 않으면 파일 이름 sans 디렉토리에 적용됩니다.
    • 패턴이 /로 끝나는 경우 디렉토리에만 적용됩니다.
    • 패턴이 /로 시작하면 rsync에 인수로 전달 된 디렉토리의 전체 경로에 적용됩니다.
    • * 단일 디렉토리 구성 요소의 하위 문자열 (즉, /와 절대 일치하지 않음); **는 모든 경로 하위 문자열과 일치합니다.
  • 소스 인수가 /로 끝나는 경우 내용이 복사됩니다 (rsync -r a/ b는 모든 b/foo마다 a/foo를 만듭니다). 그렇지 않으면 디렉토리 자체가 복사됩니다 (rsync -r a bb/a를 만듭니다).


따라서 여기서는 *.pdf를 포함하고, 디렉토리를 포함하는 디렉토리를 포함하고, 다른 모든 것을 제외해야합니다.

rsync -a --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

이렇게하면 일치하는 파일이없는 디렉토리 나 디렉토리를 포함하는 서브 디렉토리까지 모든 디렉토리가 복사됩니다. --Prune-empty-dirs 옵션으로이를 피할 수 있습니다 (디렉토리를 명시 적으로 일치 시켜도 디렉토리를 복사 할 수는 없기 때문에 보편적 인 솔루션은 아니지만 드문 경우입니다).

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/
rsync -av --include="*/" --include="*.pdf" --exclude="*" ~/Latex/ ~/Output/ --dry-run

기본값은 모든 것을 포함하는 것이므로 전송하려는 파일을 포함하여 after 모든 것을 명시 적으로 제외해야합니다. 실제로 파일을 전송하려면 --dry-run을 제거하십시오.

시작하는 경우 :

--exclude '*' --include '*.pdf'

그런 다음 욕심 매칭은 모든 것을 배제합니다.

시도하면 :

--include '*.pdf' --exclude '*' 

그런 다음 최상위 폴더에있는 pdf 파일 만 전송됩니다. 디렉토리는 '*'로 제외되므로 디렉토리를 따르지 않습니다.

30
jmanning2k

*.pdf와 같은 패턴을 사용하는 경우, 쉘은 해당 패턴을 "확장"합니다. 즉, 패턴을 현재 디렉토리의 모든 일치 항목으로 바꿉니다. 실행중인 명령 (이 경우 rsync)은 패턴을 사용하려고 시도한 사실을 인식하지 못합니다.

zsh를 사용하는 경우 쉬운 해결책이 있습니다. ** 패턴을 사용하여 폴더를 재귀 적으로 일치시킬 수 있습니다. 이 시도:

rsync -avn ~/LaTeX/**/*.pdf ~/Output/
15
Marcel Stimberg

find 및 중간 파일 목록 (files_to_copy) 문제를 해결하십시오. 홈 디렉토리에 있는지 확인한 후 다음을 수행하십시오.

find LaTeX/ -type f -a -iname "*.pdf" > files_to_copy && rsync -avn --files-from=files_to_copy ~/ ~/Output/ && rm files_to_copy

Bash로 테스트했습니다.

13
Derek Frye

manpage 의 "INCLUDE/EXCLUDE PATTERN RULES"섹션에서 판단하는 방법은 다음과 같습니다.

rsync -avn --include="*/" --include="*.pdf" ~/Latex/ ~/Output/

이것과 kbrd의 대답의 중요한 차이점은 --include="*/" 플래그-rsync가 이름이 무엇이든 관계없이 찾은 디렉토리를 복사하도록 지시합니다. 이는 rsync가 해당 서브 디렉토리를 복사하도록 지시되지 않은 한 서브 디렉토리로 재귀하지 않기 때문에 필요합니다.

또한 따옴표는 셸이 현재 디렉토리를 기준으로 패턴을 파일 이름으로 확장하지 못하도록하고 다음 중 하나를 수행하지 못하게합니다.

  1. 필터를 성공시키고 엉망으로 만들 수 있습니다 (플래그 중간에있을 가능성은별로 없지만 누군가가 --include=foo.pdf ...)

  2. Zsh가 기본적으로 발견 한 것처럼 명령을 실행하는 대신 실패하고 잠재적으로 오류가 발생합니다.

9
SamB

이것이 내가 선호하는 솔루션입니다.

find source_dir -iname '*.jpg' -print0 |  rsync -0 -v --files-from=- . destination_dir/

find 명령은 rsync :-)의 포함/제외 규칙보다 이해하기 쉽습니다.

Pdf 파일 만 복사하려면 .jpg에서 .pdf

3
guettli

이건 어때요:

rsync -avn --include="*.pdf" ~/Latex/ ~/Output/
3
kbyrd

찾기를 사용하지 않고 작동 해야하는 것이 있습니다. 이미 게시 된 답변과의 차이점은 필터 규칙의 순서입니다. rsync 명령의 필터 규칙은 iptable 규칙과 매우 유사하게 작동하며 파일과 일치하는 첫 번째 규칙이 사용됩니다. 수동 페이지 에서 :

전송할 파일/디렉토리 목록이 작성되면 rsync는 포함/제외 패턴 목록과 비교하여 전송할 각 이름을 차례로 확인하고 첫 번째 일치 패턴이 적용됩니다. 제외 패턴 인 경우 해당 파일은 다음과 같습니다. 건너 ;; 포함 패턴 인 경우 해당 파일 이름을 건너 뛰지 않습니다. 일치하는 패턴이 없으면 파일 이름을 건너 뛰지 않습니다.

따라서 다음과 같은 명령이 필요합니다.

rsync -avn --include="**.pdf" --exclude="*" ~/LaTeX/ ~/Output/

"**. pdf"패턴에 유의하십시오. man 페이지 에 따르면 :

패턴에/(후행 /를 계산하지 않음) 또는 "**"가 포함 된 경우 선행 디렉토리를 포함하여 전체 경로 이름과 일치합니다. 패턴에/또는 "**"가 포함되어 있지 않으면 파일 이름의 최종 구성 요소와 만 일치합니다. (알고리즘은 재귀 적으로 적용되므로 "전체 파일 이름"은 실제로 시작 디렉토리에서 아래로 경로의 일부가 될 수 있습니다.

작은 테스트에서는 디렉토리 트리에서 재귀 적으로 작동하며 pdf 만 선택합니다.

2
Steven D

소스 디렉토리 내부에서 헤더 (../include) 만 포함하는 디렉토리를 생성하려면 다음을 수행하십시오.

rsync -avh --Prune-empty-dirs --exclude="build" --include="*/" --include="*.h" --exclude="*" ./* ../include/

이것은 모든 빈 디렉토리와 build 디렉토리를 제외합니다.

0
SCG82