모든 PDF 파일을 이전에 존재하지 않는 별도의 디렉토리로 이동하십시오.

모든 PDF 파일을 이전에 존재하지 않는 별도의 디렉토리로 이동하십시오.

파일을 일괄 이동하는 간단한 방법을 작성 중이며 두 가지 방법을 시도했습니다.

#(1)
find . -name '*.pdf' | xargs -I{} mkdir pdfs; mv {} pdfs 

#(2)
find . -name '*.pdf' -exec mv {} pdfs \+

첫 번째 방법은 놀랍게도 "때때로" 작동했지만, PDF가 포함된 폴더를 여러 번 삭제하고 PDF를 상위 디렉터리로 반환한 후 갑자기 작동이 중지되었습니다.

다음 오류가 발생합니다.

mv: rename {} to pdfs: No such file or directory
xargs: unterminated quote

두 번째 방법은 다음 오류를 생성합니다.

find: -exec: no terminating ";" or "+"

고쳐 쓰다:

나는 다음과 같이 작동하도록 만들었습니다.

find . -name '*.pdf' -exec mv "{}" pdfs \;

그러나 다음과 같이 디렉터리를 만들고 파일을 한 줄로 이동하려는 경우에는 작동하지 않습니다.

find . -name '*.csv' -exec mkdir -p csvs && mv "{}" csvs \;

검색: -exec: ";" 또는 "+"가 끝나지 않습니다.

디렉토리를 만들고 이동하는 방법은 무엇입니까?

답변1

귀하의 상황이 실제로 그렇게 단순하다고 가정하면(.pdf로 끝나는 파일),

mv -- **/*.pdf pdfs/

할 것입니다.

zsh의 경우 재귀 glob이 기본적으로 활성화되어 있으며, bash의 경우 먼저 다음을 사용하여 **활성화해야 합니다.shopt -s globstar

귀하의 find 호출이 실제로 약간 더 복잡할 수 있다고 생각합니다. 그러나 특히 zsh를 사용하는 경우 쉘의 확장된 와일드카드 기능은 매우 강력하며 매번 작동하는 올바른 Magic Find 매개변수를 기억하는 수고를 덜어줍니다.

답변2

다음과 같이 작동해야 합니다.

$ touch foo.pdf white\ space.pdf
$ ls
 foo.pdf  'white space.pdf'
$ mkdir pdfs && \
    find . -path ./pdfs -prune \
    -o -name '*.pdf' -exec mv {} pdfs/ \;
$ tree
.
└── pdfs
    ├── foo.pdf
    └── white space.pdf
  1. 이렇게 하면 디렉터리가 생성되고 pdfs성공적으로 생성된 경우에만 계속됩니다.
  2. 이는 로 끝나는 모든 파일을 찾고 해당 파일이 디렉터리 .pdf로 이동된 파일과 일치하지 않는지 확인합니다 (이 섹션에서는 이 디렉터리의 파일을 건너뜁니다).pdfs-path pdfs -prune
  3. 이것하다mv게임당 한 번 실행됩니다. mv -t pdfs/ {} \+성능을 향상하려면 (GNU 확장)을 사용하십시오 .

답변3

따옴표가 없는 명령은 ;명령과 명령을 구분하므로 작동할 가능성이 없습니다.mvfind

지금까지 가장 쉬운 해결책은 를 실행하기 전에 대상 디렉터리를 만드는 것입니다 find. 빈 디렉터리를 유지하지 않으려면 rmdir나중에 그렇게 할 수 있습니다. 디렉터리에 파일이 포함되어 있으면 실패합니다.

GNU가 있는 경우 이동하려는 파일 앞에 대상 디렉터리의 이름을 편리하게 지정할 수 있는 옵션이 mv있습니다 .-t

mkdir pdfs
find . -name '*.pdf' -exec mv -t pdfs {} +
rmdir pdfs || true

없는 경우 mv -t다음과 같이 시도해보십시오.

find . -name '*.pdf' -exec sh -c 'mv "$@" "$0"' pdfs {} +

우리는 뻔뻔하게도 "zeroth" 매개변수를 사용하여 sh -c매개변수 목록과 별도로 대상 디렉터리 이름을 전달합니다 "$@". (관례적으로 이 "0번째" 매개변수에는 쉘 이름이 포함되지만 여기서는 아무 것도 유용하지 않고 어쨌든 문자열에 뭔가가 포함되어야 하므로 일부 수정을 가하여 처리할 필요가 없습니다. 매개변수 목록 포함.)

find ... -exec mv {} pdfs \;

mv작동하지만 발견된 각 파일에 대해 별도의 명령을 실행하므로 다소 비효율적입니다 . +터미네이터는 가능한 한 많은 파일에 대해 -exec단일 하위 프로세스( 와 유사)를 실행 하지만 토큰이 끝에 있어야 함을 의미합니다.xargs{}

답변4

한 가지 방법은 다음과 같습니다.진주의rename:

touch foo.pdf white\ space.pdf $'new\nline.pdf'
find . -name '*pdf' -print0 | rename -n -0 's|[^/]+\.pdf$|./pdfs/$&|ms'

-n시도가 만족스러우면 포기하세요.

관련 정보