파일을 일괄 이동하는 간단한 방법을 작성 중이며 두 가지 방법을 시도했습니다.
#(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
- 이렇게 하면 디렉터리가 생성되고
pdfs
성공적으로 생성된 경우에만 계속됩니다. - 이는 로 끝나는 모든 파일을 찾고 해당 파일이 디렉터리
.pdf
로 이동된 파일과 일치하지 않는지 확인합니다 (이 섹션에서는 이 디렉터리의 파일을 건너뜁니다).pdfs
-path pdfs -prune
- 이것하다
mv
게임당 한 번 실행됩니다.mv -t pdfs/ {} \+
성능을 향상하려면 (GNU 확장)을 사용하십시오 .
답변3
따옴표가 없는 명령은 ;
명령과 명령을 구분하므로 작동할 가능성이 없습니다.mv
find
지금까지 가장 쉬운 해결책은 를 실행하기 전에 대상 디렉터리를 만드는 것입니다 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
시도가 만족스러우면 포기하세요.