존재하지 않는 파일에 globbing 결과를 중괄호 확장 복사로 만들 수 있습니까?

존재하지 않는 파일에 globbing 결과를 중괄호 확장 복사로 만들 수 있습니까?

Bash에서 중괄호 확장은 와일드카드 결과를 존재하지 않는 파일에 복사하지 않습니다.

예를 들어, 현재 디렉터리에 이라는 이름의 파일이 있는데 1.epub확장자를 제외하고 동일한 파일 이름을 가진 pdf 파일로 변환하고 싶습니다. PDF 파일이 1.pdf아직 존재하지 않습니다.

$ ebook-convert *.{epub,pdf}

결과 파일은 *.pdf.

Bash에서는 먼저 epub 파일의 기본 이름을 변수로 추출한 다음 해당 변수의 값을 사용하여 pdf 파일의 이름을 지정해야 합니까?

Bash나 다른 쉘 내에 더 우아한 솔루션이 있습니까?

답변1

쉘 기술은 루프를 사용합니다.

sh 및 bash 또는 zsh와 같은 기타 sh 유사 쉘에서:

for f in *.epub; do
  ebook-convert -- "$f" "${f%.epub}.pdf"
done

zsh에서는 다음과 같이 단축할 수 있습니다.

for f (*.epub(N)) ebook-convert -- $f $f:r.pdf

Nullglob glob 한정자는 일치하는 파일이 없는 경우에도 오류를 방지합니다. bash에는 이에 상응하는 기능이 없지만 nullglobksh93에서 미리 옵션을 설정할 수도 있습니다.for f in ~(N)*.epub; do...

rename다음과 같은 프로그램이 설치되어 있을 수 있습니다 .man 1 rename

답변2

zmv의 유틸리티는 zsh모든 명령과 함께 사용할 수 있으며 다음과 같은 모드에서 사용할 수 있습니다.

autoload zmv
zmv -Wn -p ebook-convert '*.epub' '*.pdf'

시험 실행 에 사용하고 -n결과에 만족하면 제거하십시오.

별칭으로는 다음과 같이 더 짧을 수도 있습니다 ~/.zshrc.

autoload zmv
alias ebc='noglob zmv -W -p ebook-convert '

이제 명령줄은 간단합니다.

ebc *.epub *.pdf

예:

> ls *.epub
1.epub b2.epub
> ebc -n *.epub *.pdf
ebook-convert -- 1.epub 1.pdf
ebook-convert -- b2.epub b2.pdf

더 많은 사용 옵션은 다음을 zmv참조하세요.문서.

답변3

Bash에서 중괄호 확장은 와일드카드 결과를 존재하지 않는 파일에 복사하지 않습니다.

스펙에 따르면 실제로는 그렇지 않습니다. 브레이크 확장은 Bash가 모든 명령에 대해 수행하는 첫 번째 확장이고 경로 이름 확장은 마지막입니다. 그래서 당신의 명령이 수신되면

ebook-convert *.{epub,pdf}

, bash는 먼저 중괄호 확장을 수행하여

ebook-convert *.epub *.pdf

, 나중에 각 패턴에 대해 별도로 경로 이름 확장만 수행합니다. nullglob 셸 옵션을 설정하지 않으면 어떤 파일과도 일치하지 않는 glob 패턴이 자체적으로 확장되므로 이 방법을 사용하여 아직 존재하지 않는 .pdf 파일의 이름을 생성할 수 없습니다.

게다가 .epub작업 디렉터리에 여러 파일이 있거나 .pdf쓰려는 파일과 다른 파일이 있는 경우 명령은 잠재적으로 파괴적인 파일로 확장됩니다.

Bash에서는 먼저 epub 파일의 기본 이름을 변수로 추출한 다음 해당 변수의 값을 사용하여 pdf 파일의 이름을 지정해야 합니까?

실제로 EPUB 이름을 변수에 저장하는 것을 피할 수 있지만 먼저 epub 이름을 찾은 다음 개별적으로 변환을 적용해야 합니다. 특히 glob을 사용하여 EPUB를 식별하는 경우 더욱 그렇습니다.

쉘 기능을 사용하는 것이 좋습니다.

epub_to_pdf() {
  for epub; do
    ebook-convert "${epub}" "${epub%.epub}.pdf"
  done
}

정의한 후에는 해당 PDF가 아닌 EPUB를 지정하면 됩니다.

epub_to_pdf *.epub

이는 또한 여러 EPUB를 적절하게 처리합니다. 매번 함수를 정의하고 싶지 않을 수도 있지만 정의를 함수에 넣어 .bashrc항상 사용할 수 있도록 할 수 있습니다.

답변4

"우아한 솔루션"은 GNU Make의 패턴 규칙입니다. 이것이 있다면 Makefile:

%.pdf: %.epub
        ebook-convert -- $^ $@

그럼 넌 할 수 있어

$ make 1.pdf

GNU Make는 그것이 1.pdf존재하지 않으며 우리가 작성한 패턴 규칙의 왼쪽과 일치한다는 것을 발견할 것입니다 %.pdf. 패턴을 인스턴스화하고 생성된 오른쪽 부분을 확인합니다 1.epub. 그런 다음 명령을 실행합니다 ebook-convert 1.epub 1.pdf.

명령을 다시 실행하면 동일한 패턴 일치를 거친 다음 1.pdf업데이트된 명령을 살펴보고 최신 명령을 1.epub보고합니다 .1.pdf

관련 정보