
このコマンドを使用して、ディレクトリ内のすべてのイメージをモンタージュします。
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
ないでしょう。シェルを実行するように指示する必要があります。シェル引数として指定したいディレクトリをシェルに渡します。find
find
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
。
答え2
残りのコメントと同様に、-exec以外のコマンドを実行したり、ビットをwhileまたはforループにパイプしたりするには、何が必要かわかりません。 execオプションを使用すると、見つかったすべてのアイテム(相対パスではなくフルパス)の代わりに「{}」を使用できます。以下は、-execオプションとforループの簡単な例です。
$ tree
.
|-- a
| |-- a
| | `-- a
| `-- b
`-- b
|-- a
`-- b
7 directories, 0 files
$ find . -type d -exec touch {}/foo \
$ tree
.
|-- a
| |-- a
| | |-- a
| | | `-- foo
| | `-- foo
| |-- b
| | `-- foo
| `-- foo
|-- b
| |-- a
| | `-- foo
| |-- b
| | `-- foo
| `-- foo
`-- foo
7 directories, 8 files
$ for i in $(find . -type f); do mv $i $i.moved; done
$ tree
.
|-- a
| |-- a
| | |-- a
| | | `-- foo.moved
| | `-- foo.moved
| |-- b
| | `-- foo.moved
| `-- foo.moved
|-- b
| |-- a
| | `-- foo.moved
| |-- b
| | `-- foo.moved
| `-- foo.moved
`-- foo.moved
7 directories, 8 files