存在しないファイルに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

関連情報