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/
그리고 이것은 전체 파일 목록을 제공합니다. 모든 것이 첫 번째 패턴과 일치하기 때문에 ...
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 b
는 b/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 파일 만 전송됩니다. 디렉토리는 '*'로 제외되므로 디렉토리를 따르지 않습니다.
*.pdf
와 같은 패턴을 사용하는 경우, 쉘은 해당 패턴을 "확장"합니다. 즉, 패턴을 현재 디렉토리의 모든 일치 항목으로 바꿉니다. 실행중인 명령 (이 경우 rsync)은 패턴을 사용하려고 시도한 사실을 인식하지 못합니다.
zsh를 사용하는 경우 쉬운 해결책이 있습니다. **
패턴을 사용하여 폴더를 재귀 적으로 일치시킬 수 있습니다. 이 시도:
rsync -avn ~/LaTeX/**/*.pdf ~/Output/
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로 테스트했습니다.
manpage 의 "INCLUDE/EXCLUDE PATTERN RULES"섹션에서 판단하는 방법은 다음과 같습니다.
rsync -avn --include="*/" --include="*.pdf" ~/Latex/ ~/Output/
이것과 kbrd의 대답의 중요한 차이점은 --include="*/"
플래그-rsync가 이름이 무엇이든 관계없이 찾은 디렉토리를 복사하도록 지시합니다. 이는 rsync가 해당 서브 디렉토리를 복사하도록 지시되지 않은 한 서브 디렉토리로 재귀하지 않기 때문에 필요합니다.
또한 따옴표는 셸이 현재 디렉토리를 기준으로 패턴을 파일 이름으로 확장하지 못하도록하고 다음 중 하나를 수행하지 못하게합니다.
필터를 성공시키고 엉망으로 만들 수 있습니다 (플래그 중간에있을 가능성은별로 없지만 누군가가 --include=foo.pdf
...)
Zsh가 기본적으로 발견 한 것처럼 명령을 실행하는 대신 실패하고 잠재적으로 오류가 발생합니다.
이것이 내가 선호하는 솔루션입니다.
find source_dir -iname '*.jpg' -print0 | rsync -0 -v --files-from=- . destination_dir/
find
명령은 rsync
:-)의 포함/제외 규칙보다 이해하기 쉽습니다.
Pdf 파일 만 복사하려면 .jpg
에서 .pdf
이건 어때요:
rsync -avn --include="*.pdf" ~/Latex/ ~/Output/
찾기를 사용하지 않고 작동 해야하는 것이 있습니다. 이미 게시 된 답변과의 차이점은 필터 규칙의 순서입니다. rsync 명령의 필터 규칙은 iptable 규칙과 매우 유사하게 작동하며 파일과 일치하는 첫 번째 규칙이 사용됩니다. 수동 페이지 에서 :
전송할 파일/디렉토리 목록이 작성되면 rsync는 포함/제외 패턴 목록과 비교하여 전송할 각 이름을 차례로 확인하고 첫 번째 일치 패턴이 적용됩니다. 제외 패턴 인 경우 해당 파일은 다음과 같습니다. 건너 ;; 포함 패턴 인 경우 해당 파일 이름을 건너 뛰지 않습니다. 일치하는 패턴이 없으면 파일 이름을 건너 뛰지 않습니다.
따라서 다음과 같은 명령이 필요합니다.
rsync -avn --include="**.pdf" --exclude="*" ~/LaTeX/ ~/Output/
"**. pdf"패턴에 유의하십시오. man 페이지 에 따르면 :
패턴에/(후행 /를 계산하지 않음) 또는 "**"가 포함 된 경우 선행 디렉토리를 포함하여 전체 경로 이름과 일치합니다. 패턴에/또는 "**"가 포함되어 있지 않으면 파일 이름의 최종 구성 요소와 만 일치합니다. (알고리즘은 재귀 적으로 적용되므로 "전체 파일 이름"은 실제로 시작 디렉토리에서 아래로 경로의 일부가 될 수 있습니다.
작은 테스트에서는 디렉토리 트리에서 재귀 적으로 작동하며 pdf 만 선택합니다.
소스 디렉토리 내부에서 헤더 (../include) 만 포함하는 디렉토리를 생성하려면 다음을 수행하십시오.
rsync -avh --Prune-empty-dirs --exclude="build" --include="*/" --include="*.h" --exclude="*" ./* ../include/
이것은 모든 빈 디렉토리와 build
디렉토리를 제외합니다.