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
N
ullglob glob修飾子は、一致するファイルがない場合でもエラーを防ぎます。 bashには対応する機能はありませんが、nullglob
ksh93で事前にオプションを設定することもできます。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