파이프를 사용하여 출력 파일 이름을 지정하는 방법은 무엇입니까?

파이프를 사용하여 출력 파일 이름을 지정하는 방법은 무엇입니까?

나는 디렉토리와 그 하위 디렉토리에 있는 파일 목록을 반환하기 위해 find를 사용합니다.

find $directory -type f -name "*.epub"

그런 다음 입력 및 출력 파일 이름을 지정해야 하는 명령을 사용하고 싶습니다.

ebook-convert input.epub output.txt

출력이 입력과 동일한 디렉터리/하위 디렉터리에 저장되도록 .epub각각 을 변환하고 싶습니다 . .txt간단한 파이프는 작동하지 않습니다.

find $directory -type f -name "*.epub" | ebook-convert

어떻게 해야 하나요?

답변1

비결은아니요파일 목록을 생성한 다음 이를 반복합니다(예:찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?).

find "$directory" -type f -name '*.epub' -exec ebook-convert {} output.txt \;

*.epub이것은 일치하는 이름을 가진 디렉토리 안이나 아래의 모든 일반 파일을 찾습니다 $directory. 각 명령은 ebook-convert발견된 파일의 경로 이름을 첫 번째 및 output.txt두 번째 인수로 사용하여 실행됩니다.

이는 분명히 output.txt발견된 모든 파일을 덮어쓰지만, 다음은 -converted.txt원본 파일과 동일한 이름의 파일을 생성하고 이름 끝에 (원본 파일과 동일한 디렉터리에) 추가하여 이 문제를 해결합니다.

find "$directory" -type f -name '*.epub' -exec ebook-convert {} {}-converted.txt \;

이것가능한find두 번째 파일을 찾은 파일의 경로 이름으로 대체할 수 없기 때문에 의 모든 구현에서 작동하지 않습니다 {}(다른 문자열과 연결되어 있지만 예를 들어 GNU가 find처리하므로). 이 문제를 해결하려면:

find "$directory" -type f -name '*.epub' -exec sh -c '
    for pathname do
        ebook-convert "$pathname" "$pathname"-converted.txt
    done' sh {} +

다음 과 같은 와일드카드 패턴을 지원하는 셸을 사용하세요 bash.zsh**

for pathname in "$directory"/**/*.epub; do
    ebook-convert "$pathname" "$pathname"-converted.txt
done

(이것은 필요 shopt -s globstar하며 bash처리 됩니다.어느*.epub(.)in을 사용 zsh하거나 -ffor in을 명시적으로 테스트 하지 않는 한 일반 파일뿐만 아니라 이름과도 일치합니다 bash.

관련 정보