1000個のファイルに対して次のコマンドを実行しています。
ebook-convert <name-of-first-file>.epub <name-of-first-file>.mobi
ebook-convert <name-of-second-file>.epub <name-of-second-file>.mobi
明らかに、1000個のファイルに対してこのタスクを手動で実行するのではなく、このタスクのbashスクリプトを作成できます。
Linuxでこれを行うより簡単な方法があるかどうか疑問に思います。
ebook-convert *.epub *.mobi
上記のシナリオに適用されるのと同様の方法でワイルドカードを使用できますか?
答え1
ワイルドカードを使用してこれを直接行うことはできませんが、for
ループを使用できます。
for epub in ./*.epub; do ebook-convert "${epub}" "${epub%.epub}.mobi"; done
Zshはこのループのよりエレガントなフォーマットをサポートしています。。
ファイル名にスペース文字が含まれておらず、通常Makeとシェルで安全に処理できる場合は、シェルスクリプトの代わりにGNU Makeを使用できますMakefile
。
all: $(patsubst %.epub,%.mobi,$(wildcard *.epub))
%.mobi : %.epub
ebook-convert ./$< ./$@
その後、実行すると、make
すべての.epub
ファイルが1つのファイルに変換されます.mobi
。ファイルを更新するために、必要に応じてこのコマンドを繰り返し実行できます。このコマンドは、欠落しているファイルまたはソースファイルより古いファイルのみをビルドします。 (ebook-convert
行が空白ではなくタブで始まることを確認してください。)
答え2
シェルを含むzsh
:
for f (./*.epub) ebook-convert $f $f:r.mobi
/など、$f:r
ルート名(拡張子のない部分)に拡張されます。$f
csh
vim
または:
autoload -Uz zmv # best in ~/.zshrc
zmv -P ebook-convert './(*).epub' './$1.mobi`
(オプションの区切り文字がebook-convert
認識されないようで、で始まるファイル名を処理できる代わりにプレフィックスを使用して使用する必要があります)--
./
-P
-p
-
zmv
主に一括名前変更に使用されますが、/を使用した一括コピー/リンクに使用するか、-C
プログラムを使用するように指定することで、任意の形式の変更/変換に拡張できます。-L
-p
-P
または:
autoload -Uz zmv
alias ebc='noglob zmv -WP ebook-convert'
ebc ./*.epub ./*.mobi
-W
、を使用してzmv
ソースパターン内のすべてのワイルドカードをキャプチャし、交換時に増分などを使用してすべての${1}
ワイルドカードを変換します。引用を避けるには、コマンドパラメータでワイルドカードを無効にします${2}
。zmv -W './*.epub' './*.mobi'
zmv -W './(*).epub' './${1}.mobi'
noglob
または:
autoload -Uz zargs # best in ~/.zshrc
zargs -I@ ./*.epub(:r) -- ebook-convert @.epub @.mobi
zargs
パラメーターのリストをバッチ処理するzsh
のと似たコマンドです。ファイルのルート名を取得し、実行コマンドラインを使用して各ルート名を各ファイルのルート名に順番に変更します。xargs
./*.epub(:r)
.epub
-I@
zargs
ebook-convert
@
ebook-convert
acceptコマンドが呼び出されたら、ebook-convert file1.epub file1.mobi file2.epub file2.mobi ...
次のこともできます。
ebook-convert ./*.epub(e['reply=($REPLY $REPLY:r.mobi)'])
./file1.epub
./file1.mobi
./file2.epub
./file2.mobi
e
val glob修飾子は、一致する各ファイルに対して提供されたコードを実行するため、globは...に展開されます。ここで設定は、glob$reply
が拡張されるべき引数のリストを定義します。
または:
(){epub-convert $^@.{epub,mobi};} ./*.epub(:r)
ファイルのルート名のリストを.epub
匿名関数に渡します。この関数は中括弧拡張を使用して引数.epub
と.mobi
追加の引数を渡します。
これらすべてで*.epub
まだ新しい対応項目がない.mobi
ファイルにglob拡張を制限するには、e['[[ ! $REPLY:r.mobi -nt $REPLY ]]']
glob修飾子を追加するか、ループの一部としてスキャンを追加できます。
for epub (./*.epub) {
mobi=$epub:r.mobi
[[ $mobi -nt $epub ]] || ebook-convert $epub $mobi
}
答え3
上記のシナリオに適用されるのと同様の方法でワイルドカードを使用できますか?
ebook-convert *epub *mobi
ワイルドカード(実際の「シェルワイルドカード」)が機能する方法のため、そうではありません。ただし、ワイルドカードで始めることができます。
概念的には、シェルワイルドカードは非常に簡単です。そのワイルドカードに一致するすべてのファイルを見つけて、そのワイルドカードをそのファイルのリストに置き換え、スペースやその他の「特殊」文字を処理して、呼び出される操作(通常はプログラム、ここではebook-convert
)が各ファイルを取得します。ファイルを1つの別々の引数として保存します。
したがって、 と を含むフォルダが与えられると、シェルは呼び出される項目a.epub
(b.epub
ここfile with spaces.epub
) に対する 3 つの別々の引数*.epub
にa.epub
、b.epub
と に拡張されます。file with spaces.epub
ebook-convert
同じフォルダが与えられた場合、一致*.mobi
するものがないため、ebook-convert
リテラル引数を受け取ります*.mobi
。ebook-convert
観点から見ると、3つのepubファイルのリストと存在しない1つのmobiファイルのリストを取得します。引数リストで行うことはこれに依存します(引数が多すぎると文句を言うか、各ファイルを追加しようとしていると思います)。順番に)epubは文字通り「*.mobi」という名前のmobiファイルに変換されます。
プログラム(または組み込みシェル、関数、またはスクリプトなど)がファイル名であると予想していますが、globを含む引数を処理する方法についてのグローバルな保証はありません。通常、引数は文字列リテラルとして扱われ、存在しないかの*.mobi
ように反応しanything_else.mobi
ますが、このようなことが起こらなければならないという法的要件はありません。
たとえば、他のグローブでも同様です。は?.epub
含まれますが、含まれていません。a.epub
b.epub
file with spaces.epub
他の方々が指摘したように、できるglobを使用してループ駆動 -for file in *.epub ; do ...
スペースを処理するには、「file」への参照が必要であることに注意してください。ワイルドカードはループ自体の単一引数であることをfor file in *.epub
保証するだけであり、ループ本体には拡張されません(3つの個別のパラメータなど)。 :、および)について。file with spaces.epub
for
for file in *.epub ; do ebook-convert $file
file with spaces.epub
file
with
spaces.epub
これはすべてglob文字を必要とするプログラムの引数を引用する必要がある理由です。これにより、シェルがglobを拡張するのを防ぎ、実際に呼び出されたプログラムがユーザーが作成した引数を見ることができます。たとえば、find . -type f -name '*.epub'
このディレクトリとすべてのサブディレクトリにあるすべてのepubファイルを見つけて名前を印刷します。引数としてfind . -type f -name *.epub
見ることができますが、どうすればいいかわからないため、エラーが発生します。b.epub
file with spaces.epub
答え4
%.mobi: %.epub
私はGNU makeとファイル名の制限なしにいくつかのラッパーを使ってGNU makeで許可されているかわいい答えのようなことをすることができると思います。
from_to(){
sp=${1%%%*}; ss=${1#*%}; shift
dp=${1%%%*}; ds=${1#*%}; shift
for s in "$sp"*"$ss"; do
d=${s#"$sp"}; d=$dp${d%"$ss"}$ds
"$@" "$s" "$d" || exit 1
done
}
次のように使用できます。
from_to %.epub %.mobi ebook-convert
from_to dir1/book_%.epub dir2/%.mobi ebook-convert
模擬テストの例:
% touch {1,2,3}.foo
% from_to ./%.foo bar/%.baz echo translate --
translate -- ./1.foo bar/1.baz
translate -- ./2.foo bar/2.baz
translate -- ./3.foo bar/3.baz
*
とにかく、Unixシェルでは非常に明確な意味を持っているので、他のものを使用する必要があります。