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


128

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

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

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

zsh를 사용하고 있습니다. 내가 bash는 심지어 같은 일을하고있는 노력 모든 하위 디렉토리에있는 모든 단일 파일을 나열 필터 ... 무슨 일이야?

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


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

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

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


어, 당신은 옳은 것 같습니다 ... 나는 내 대답 (zsh의 **패턴을 사용하여 )이 작동해야한다고 생각합니다.
Marcel Stimberg

답변:


248

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/fooa/foorsync -r a bb/a


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

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

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

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

내 솔루션 (zsh의 **패턴 사용)과 달리 대상 디렉토리의 디렉토리 구조가 다시 작성됩니다. 나는 ... 이것이 OP가 원하는 무엇인지 잘 모르겠어요
마르셀 Stimberg

하나의 디렉토리 만 포함하고 나머지 디렉토리는 모두 /etc/lsyncd/lsyncd.conf.lua파일 에서 제외하고 싶습니다 . 어떤 아이디어가 있습니까?
Dhaduk Mitesh

@DhadukMitesh lsyncd에 익숙하지 않습니다. 이것을 새로운 질문으로해야합니다.
Gilles

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

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

시작하는 경우 :

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

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

시도하면 :

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

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


2
2014-03-17 현재 이것은 원래 포스터 문제를 정확하게 해결하기 때문에 가장 좋은 대답 입니다. 투표 해주세요! 추가 --prune-empty-dirs(또는 바로 가기 -m)를 사용하는 경우, 알림이나 구조적 청사진으로 원하는 것을 제외하고 대상에 빈 디렉토리를 많이 남겨 둘 수도 있습니다.
porg

1
가장 좋은 대답은 --include = "* /"가 핵심입니다.
Martin Konicek

하나의 디렉토리 만 포함하고 나머지 디렉토리는 모두 /etc/lsyncd/lsyncd.conf.lua파일 에서 제외하고 싶습니다 . 어떤 아이디어가 있습니까?
Dhaduk Mitesh

15

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

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

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

현재 디렉토리 내 어딘가에서 모든 PDF 파일을 복사하지 않을 것이라고 하고 ~ / 출력에 ~ / 유액 / 이르기까지?
SamB

나는 당신이 의미한다고 생각 rsync -avn ~/LaTeX/**/*.pdf ~/Output하지만, 해결책 --include은 어쨌든 더 확장 가능합니다.
Adam Byrtek

죄송합니다. 서두르면서 잘못 입력 한 명령을 수정했습니다 ... 포함 명령 (SamB 버전)이 더 좋지만 rsync에 대해 조금 더 복잡하고 구체적이지만 **다른 상황에서도 편리 할 수 ​​있습니다.
Marcel Stimberg

1
Bash 4는 동일한 기능을 채택했습니다. 아, 그리고 당신은 여기서 rsync를 필요로하지 않습니다, cp는 할 것입니다. 일부 시스템에서 파일이 많은 경우 cd ~/Latex && cp -p **/*.pdf ~/Output"명령 줄이 너무 깁니다"오류를 피하는 데 도움이됩니다 .
Gilles

1
포함 및 제외 필터에 사용 된 rsync의 패턴에도 동일한 기능을하는 **가 있습니다. 다른 쉘에서 인용 부호를 넣어 *를 피할 수 있습니다.
Dan Pritts

13

당신이 사용할 수있는 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로 테스트했습니다.


find가 가장 강력한 솔루션이라고 생각하지만 finds -exec옵션을 사용하거나을 사용하도록 선택합니다 xargs. 뭔가 같은 :find LaTeX/ -type f -iname "*.pdf" -print0 | xargs -0 -i rsync -avn {} Output/
스티븐 D

그래 ... 나뿐만 아니라 발견 ... 내가 rsync를 상상하지만 좋을 것 있어야 이 작업을 수행 할 수 있습니다.
개브.

이것은 더 어려운 문제에 대한 깔끔한 해결책입니다. 아마도이 클래스를 사용하여 문서 클래스가 standalone있거나 .tex같은 이름을 가진 파일 이없는 파일을 제외 할 수 있습니다. 이러한 파일 은 일부 문서에 포함 된 이미지이므로 ...
시무스

2
rsync 옵션 --files-from은 stdin에서 읽는 것을 허용합니다. 이 일 것 find LaTeX/ -type f -a -iname "*.pdf" | rsync -avn --files-from=- ~/ ~/Output/
후안 칼레에게

9

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

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

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

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

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

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


따라서 이것은 PDF와 디렉토리 구조 만 복사하지만 kbrd는 파일을 복사하지만 구조는 무시합니까?
Seamus

1
흠. 이것은 실제로 여전히 모든 것을 시도하고 복사하는 것 같습니다. 왜냐하면 그것이 필터가없는 것이므로 include이미 추가 항목을 가져도 아무것도 변하지 않습니다. 내가 무슨 뜻인지
알면

7
다음에 필요 --exclude="*"합니다 --include="*.pdf". 그렇지 않으면 모든 것이 전송됩니다.
jmanning2k

@ jmanning2k : 아. 알아 둘만 한!
SamB

4

이것은 어떤가요:

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

아니요, man rsync옵션 뒤에 그리고 소스 / 대상 앞에 필터를 넣습니다. 나는 이것을 시도했는데 작동하지 않았다
Seamus

귀하의 방법은 현재 폴더에서 .pdf 파일을 찾지 만 원하는대로 재귀 적으로 찾을 수는 없습니다. ( a옵션은 아카이브를위한 것이며 무엇보다도 복사를 재귀 적으로 만듭니다.
Seamus

1
죄송합니다. 답변을 업데이트했습니다.
kbyrd

+1하여 매뉴얼 페이지에서 관련 자료를 찾는 방법에 대한 힌트를 얻었습니다. (바람직하게 나는 그것을 올바르게 얻었다. :-)
SamB

3

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

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

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

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

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

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

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


정확히 어떻게 테스트 했습니까? 설명서 및 실험적 검증에 대한 나의 이해에 따르면, 귀하의 명령은 *.pdf최상위 디렉토리 에만 복사해야합니다 (그러나 아님 ~/LaTeX/foo/bar.pdf).
Gilles

@ 질 Crud. 네 말이 맞아 나는 이것을 테스트하고 맹세했지만 그것을 재현 할 수는 없다고 맹세했다. 그리고 실제로 인용 한 매뉴얼 페이지를 읽었으므로 작동하지 않는 것이 좋습니다. 불평.
Steven D

1
글쎄, 나는 내 시험이 어디에서 잘못되었는지 알아 냈다. 내 "작은 테스트"는 내 자신의 .tex 및 .pdf 파일이있는 디렉토리에있었습니다. 그런 다음 "test"하위 디렉토리와 해당 하위 디렉토리에 test.pdf 및 test.tex를 작성했습니다. 그러나 LaTeX 실험 중 빠른 것으로 인해 최상위 디렉토리에 test.pdf가 있음을 알지 못했습니다.
Steven D

나는 여전히을 이해하지 못한다 **. 예를 들어서 좋을 것입니다. ;)
buhtz

2

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

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

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

pdf 파일 만 복사하려면 다음 .jpg으로 변경하십시오 ..pdf

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.