私はかなり簡単なことをしたいです。montage
何千もの画像があるディレクトリで作業したいのですが、次のオプションはほとんどありません。
me@home$ montage -size 256x256 DSC01*.JPG.svg output.png
...しかし、一度に約100枚の画像しかキャプチャできないので十分ではありません。
me@home$ montage -size 256x256 *.svg output.png
...結果ファイルが大きすぎて解析できないため、すべての画像を同時にインポートします。
私は何ですか?したい一度に100〜200個のファイルを繰り返すだけです。 forループ(?)を使用すると、これを行うことができるようですが、どうすればよいか少し混乱しています。私はそれを行うための賢い方法があると思いましたか、find -exec
それをxargs
考えませんでした。使用していますが、bash
時々zsh
使用します。
要約すると、私は2600個のイメージファイルが与えられればモンタージュを約13~26回(100~200個のファイルごとに1回)呼び出し、n個のファイルが与えられればn回の倍数で呼び出せるライナーを探しています。
答え1
bash
いくつかの修正で特別な配列属性を使用する1つのアプローチzsh
は次のとおりです。
image_files=(*.svg) # use your own glob expression
n=200 # number of files per command line; adjust to taste
for ((i=0; i < ${#image_files[@]}; i+=n)); do
montage -size 256x256 "${image_files[@]:i:n}" output-"$i".png
done
答え2
xargsを使用してこれを行うことができます。残念ながら、-I(コマンドラインの途中に挿入するため)と-L(実行ファイルへの単一呼び出しでファイル数を制限するため)を組み合わせることは不可能です。したがって、例として次のコマンドラインを作成しました(ただし、ファイル名の特殊文字はサポートされていませんので注意してください)。
ls . | \
xargs -n 100 echo | \
(a=1;
while read args; do
echo montage -size 256x256 $args output-$a.png;
a=$((a+1));
done
)
echo
実際にコマンドを実行するには削除してください。
指示:
- ファイル名にはスペースやその他の特殊文字を含めないでください。
- 最後のモンタージュ行には、ファイルが 100 個未満の場合があります。
修正する:
以下は、ファイル名の空白の問題を解決する対応するforループです。
a=0
b=0
lst=
for f in *; do
a=$((a+1))
lst="$lst '$f'"
if test $a -ge 100; then
eval echo montage --args $lst target-$b.png
b=$((b+1))
a=0
lst=
fi
done
アップデート2:ファイル名の特殊文字の影響を受けないPythonソリューション
#!/usr/bin/env python
# iterate.py
"""Usage:
%prog <number per call> <file pattern> <command prefix> -- <command postfix>
e.g. %prog 100 "DSC01*.jpg.svg" montage -size 256x256 -- output-%i.png """
import sys,subprocess,glob,os
if len(sys.argv) < 5:
print __doc__.replace("%prog", os.path.basename(sys.argv[0]))
sys.exit(1)
def chunks(l, n):
for i in xrange(0, len(l), n): yield l[i:i+n]
num, pattern, args = int(sys.argv[1]), sys.argv[2], sys.argv[3:]
files, idx = glob.glob(pattern), args.index("--")
before, after = args[0:idx], args[idx+1:]
for idx,chunk in enumerate(chunks(files,num)):
subprocess.call( before + chunk + [s.replace("%i",str(idx)) for s in after] )
答え3
GNU Parallelでは、次のことができます。
parallel -N200 montage -size 256x256 {} output{#}.png ::: *.svg
通常、GNU Parallelが期待しているように、特殊文字を持つファイルには確かに安全です。
最小設置
パラレルのみが必要で、「make」がインストールされていない場合(システムが古くなったり、Microsoft Windowsの場合があります):
wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
mv parallel sem dir-in-your-$PATH/bin/
簡単な紹介については、紹介ビデオをご覧ください。 https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1または http://tinyogg.com/watch/TORaR/そしてhttp://tinyogg.com/watch/hfxKj/
答え4
これはすべてのファイル名に安全ですが、数を保存するために一時ファイルが必要なxargsを使用するバージョンです。モンタージュあたりのファイル数を調整するには、「-n 100」を調整します。 「printf」を「find -print0」に置き換えることもできますが、「count.temp」が見つからないことを確認してください。
echo 1 >count.temp
printf "%s\0" *.svg | xargs -0 -n 100 sh -c '
a=`cat count.temp`
montage --blah "$@" output-"$a".png
let a=a+1
echo "$a" >count.temp
'
rm count.temp