질문

질문

수천 개의 PDF 파일을 한 폴더에 반복적으로 압축할 계획입니다.

다음 루프를 사용해 보았습니다.

#!/bin/bash
find "/home/user/original" -type f -name *.pdf | while read -r file
do
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress -dNOPAUSE -dBATCH -dQUIET -sOutputFile="/home/user/processed$file" "$file"
done

($file이 시작 부분에 /를 갖고 있고 processor/$file도 시도했기 때문에 processor$file을 사용했습니다)

어쨌든 루프를 실행하면 다음과 같은 오류가 발생합니다.

GPL Ghostscript 9.26: **** Could not open the file /home/user/processed/home/user/original/test001.pdf .
**** Unable to open the initial device, quitting.

어떤 이유로 path/to/output/path/to/input에서 pdf를 찾고 있습니다. / 대신 ./로 링크를 변경해 보았으나 소용이 없었습니다.

다음 명령을 단독으로 실행하면 압축된 PDF가 정상적으로 출력됩니다.

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress -dNOPAUSE -dBATCH -dQUIET -sOutputFile="/home/user/processed/output.pdf" "input.pdf"

루프가 작동하지 않는 이유에 대한 아이디어가 있습니까?
PS 모든 디렉토리는 이제 권한 오류가 없는지 확인하기 위해 777입니다.

답변1

질문

기본적으로 find다음 작업이 수행됩니다 -print.

 -print

True이면 표준 출력에 전체 파일 이름을 인쇄하고 그 뒤에 개행 문자가 옵니다.

"전체 파일 이름"은 각 파일의 절대 경로가 표시된다는 의미입니다.

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

그래서 당신이 사용할 때

gs -sOutputFile="/home/user/processed$file"

...루프 내부에는 변수가 $file포함되며 /home/user/original/test001.pdf전체 표현식은 연결된 두 경로로 확장됩니다.

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

표시되는 오류 메시지는 다음을 반영합니다.

Could not open the file /home/user/processed/home/user/original/test001.pdf

기본 이름 사용

파일의 기본 이름만 필요한 경우(모든 파일이 동일한 소스 폴더에 있으므로) find다른 출력 형식을 사용하도록 지시할 수 있습니다.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

사실; 인쇄체재표준 출력에서는 "\" 이스케이프 문자와 "%" 지시문을 해석합니다.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).

상대적인 이름을 사용하세요

또는(입력 파일이 다른 디렉터리에 있는 경우) 정리해야 합니다.일부디렉토리 경로. 예를 들어 사용할 수 있습니다. cut그 이유는 다음과 같습니다.

find "/home/user/original" -type f -name *.pdf | cut -d/ -f5- | while read -r file
do
    gs [...] -sOutputFile="/home/user/processed/$file" "/home/user/original/$file"

/그러면 4번째 입력까지의 모든 내용이 삭제됩니다. 그러나 입력 트리의 구조와 일치하도록 새 출력 디렉터리 생성을 처리하지 않습니다.

답변2

여러 테스트를 거친 후 Ghostscript에서 다음 동작을 관찰했습니다. 출력 파일을 로 지정하면 /home/user/processed/home/user/original/test001.pdf명령 gs은 파일( /home/user/processed/home/user/original/)에 대한 경로가 이미 존재한다고 예상합니다. 소스의 폴더 구조가 현재 대상에 존재하지 않기 때문에 명령에서 오류가 발생하고 대상 파일을 열 수 없다는 메시지가 나타납니다.

이 문제를 해결하려면 먼저 다음 명령을 사용하여 폴더 구조를 다시 만들 수 있습니다.

cd /home/user/original
find . -type d -exec mkdir -p -- /home/user/processed/{} \;

이 작업이 완료되면 스크립트를 실행하여 PDF 파일을 생성할 수 있습니다. 귀하의 명령을 사용하여 PDF 파일을 생성할 수 있으므로 gs다른 문제는 없다고 가정합니다.

스크립트가 완료된 후 대상에 빈 디렉토리가 있다고 의심되어 이를 삭제하려는 경우 다음 find 명령을 사용하십시오.

find /home/user/processed/ -type d -empty -delete

관련 정보