폴더의 파일을 폴더 내의 파일 .docx
로 재귀적으로 변환하고 싶습니다 . .doc
문제는 모든 출력 파일이 소스 파일 위치가 아닌 다음 명령을 실행하는 폴더에 생성된다는 것입니다.
find -type f -name "*.docx"-exec libreoffice --convert-to doc {} \;
libreoffice
find 는 명령에 소스 파일을 제공하고 출력은 분명히 현재 위치에 있어야 한다는 것을 알고 있습니다 . 그렇다면 명령을 사용하여 폴더를 반복적으로 반복하고 파일이 발견된 위치에서 명령을 실행하려면 어떻게 해야 합니까? 초기보다는?
답변1
-execdir
당신이 그것을 지원한다면 그것이 목적입니다 find
. Linux 시스템의 기본 GNU에는 find
이 기능이 있습니다. 에서 man find
:
-execdir 명령;
-execdir 명령{} +
-exec와 비슷하지만 지정된 명령은 일반적으로 검색을 시작한 디렉터리가 아닌 일치하는 파일이 포함된 하위 디렉터리에서 실행됩니다. [. . . ]
그래서 당신은 다음을 원합니다:
find . -type f -name "*.docx" -execdir libreoffice --convert-to doc {} \;
파일 이름은 각 인스턴스에 삽입됩니다 {}
. -exec
사용하는 경우 {}
로 시작하는 상대 경로가 포함됩니다 ./
. -execdir
사용하는 경우 {}
파일 이름만 사용합니다.
답변2
이를 수행하려면 find 출력을 쉘 명령에 전달할 수 있어야 합니다.
find . -type f -name \*.docx -exec sh -c 'echo libreoffice --convert-to-doc {} --outdir $(dirname {})' \;
댓글에서 @EdgarMagallon의 제안은 실제로 내 것보다 간단합니다. 물론, 이 사용 사례에서는 그의 명령을 추천합니다.
답변3
문제는 -execdir
다음을 교체 하여 해결됩니다.-exec
find . -type f -name "*.docx" -execdir libreoffice --convert-to doc {} \;
답변4
--output-dir
문서가 있는 디렉토리를 사용 하거나 해당 디렉토리로 변경하십시오. 아래에서는 비표준(그러나 일반적으로 구현되는) -execdir
조건 자를 사용하지 않고 이를 수행하는 방법을 보여 드리겠습니다 find
.
이는 발견된 파일의 경로 이름을 해당 파일을 반복하는 짧은 인라인 스크립트에 전달합니다. 발견된 각 이름에 대해 스크립트는 파일이 발견된 디렉터리로 변경되고 그곳에서 변환을 수행합니다. 이는 cd
서브셸에서 수행되므로 나머지 스크립트 환경은 영향을 받지 않습니다.
find . -name '*.docx' -type f -exec sh -c '
for pathname do
( cd "$(dirname "$pathname")" && libreoffice --convert-to doc "$(basename "$pathname")" )
done' sh {} +
다음은 유사하지만 작업 디렉터리를 변경하지 않습니다. 대신 --outdir
옵션을 사용하여 변환된 문서가 기록될 디렉터리 경로를 지정합니다.
find . -name '*.docx' -type f -exec sh -c '
for pathname do
libreoffice \
--convert-to doc "$pathname" \
--outdir "$(dirname "$pathname")"
done' sh {} +
위의 쉘 코드에서는 (remove the shortest suffix string match ) "$(dirname "$pathname")"
로 대체할 수 있고 , (remove the longest prefix string match ) 로 대체할 수 있다 ."${pathname%/*}"
"$pathname"
/*
"$(basename "$pathname")"
"${pathname##*/}"
"$pathname"
*/