各サブディレクトリでワイルドカードを使用してコマンドを実行する

各サブディレクトリでワイルドカードを使用してコマンドを実行する

このコマンドを使用して、ディレクトリ内のすべてのイメージをモンタージュします。

gmic *jpg -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o -0000."$(date)".jpg

このコマンドをディレクトリとそのサブディレクトリで繰り返し実行したいと思います。したがって、各ディレクトリでそのディレクトリにあるイメージのモンタージュを作成します。

私は試した:

find -exec gmic *jpg -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o -0000."$(date)".jpg

しかし、これによりエラーが発生しました。

find: missing argument to `-exec'

私も試しました

find -exec gmic -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o -0000."$(date)".jpg {} \;

これにより、次のエラーが発生します。

[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Output image [] as file '-0000.Fri Mar 13 04:33:44 EDT 2015.jpg', with quality 100%.
[gmic]-0./ *** Error *** Command '-output': File '-0000.Fri Mar 13 04:33:44 EDT 2015.jpg', instance list (0,(nil)) is empty.
[gmic] *** Error in ./ *** Command '-output': File '-0000.Fri Mar 13 04:33:44 EDT 2015.jpg', instance list (0,(nil)) is empty.

ベストアンサー1

いいですね。ディレクトリツリーのすべてのディレクトリ(現在のディレクトリ、サブディレクトリ、サブディレクトリなど)でコマンドを実行しようとしています。最初にすべきことは、問題のディレクトリを列挙することです。findディレクトリのみをリストするように指示するには、次のコマンドを使用します。

find . -type d

各ディレクトリで実行するコマンドは次のとおりです。

gmic ./*jpg -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o -0000."$(date)".jpg

これは、ワイルドカード拡張とコマンド置換を含むシェルコマンドです。これを実行するにはシェルを実行する必要があります。シェルが何をすべきかを指示されるので、あなたが実行しているシェルではfindないでしょう。シェルを実行するように指示する必要があります。シェル引数として指定したいディレクトリをシェルに渡します。findfind

find . -type d -exec sh -c '…' {} \;

このスクリプトを呼び出す前に、gmicこのスクリプトでいくつかのタスクを実行する必要があります。関連ディレクトリに変更し、.jpgファイルが含まれていることを確認します。

find . -type d -exec sh -c '
  cd "$0" || exit
  set -- *.jpg
  if [ -e "$1" ]; then
    gmic "$@" -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o -0000."$(date)".jpg
  fi
' {} \;

または、ファイルを一覧find表示するように指示できます。.jpgただし、これはディレクトリごとに1つのコマンドしか実行するのが困難です。

シェルがプレーンではなくbashの場合は、ワイルドカードを使用してディレクトリに再帰できますsh**を使用するよりも簡単ですfind。 Bash 4.2以降では、**ディレクトリのシンボリックリンクを閲覧することにも注意してください。ファイル存在テストを少し簡単にすることもできます。

shopt -s globstar nullglob
for dir in ./**/*/; do
  files=("$dir/"*.jpg)
  if [[ ${#files[@]} -ne 0 ]]; then
    gmic "${files[@]}" -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o "$dir/-0000.$(date)".jpg
  fi
done

zshでは利用可能です履歴修飾子グローバル予選ファイルを含むディレクトリを列挙し、結果の配列を.jpgフィルタリングして各ディレクトリの単一コピーを保持します。

dirs=(./**/*.jpg(:h))
for dir in ${(u)dirs}; do
  gmic $dir/*.jpg -gimp_montage 4,\""V(H(0,1),H(2,V(3,4)))"\",1,1.0,0,5,0,0,0,255,0,0,0,0 -o "$dir/-0000.$(date).jpg"
done

(余談:-0000.Sat Mar 14 15:51:28 CET 2015.jpgそれはファイルの非常に奇妙な名前です。名前で始まるファイルは-コマンドのオプションのように見えるため、問題を引き起こす傾向があります。アルファベット順に並べ替えることは、年代順に並べ替えるのと同じ形式で日付に対してより便利に動作します20150314-145128

おすすめ記事