web-dev-qa-db-ja.com

Linuxの検索から親と祖父母のディレクトリにアクセスしてxargsに渡す

ディレクトリ内のすべてのtiffでimagemagickのバッチ変換を実行しようとしています。

ディレクトリの構造は次のようになります。

test    
    123
       456
          image.tif

    256
       857
          anotherimage.tif

Findを使用してすべての画像を見つけ、それらをxargsに渡してimagemagickをjp2に変換しようとしています。出力ファイル名は、親ディレクトリ名と親ディレクトリ名の組み合わせになるため、上記の例では、image.tif123456.jp2に変換されます。

findは正常に機能していますが、imagemagickの正しい組み合わせを取得できず、必要なものを実現するためのパラメーターを見つけることができません。これがxargsでの検索です。 {grandparentdir}と{parentdir}は、欠落しているビットのプレースホルダーです。

find /var/tmp/test -type f \( -name "*.tif" -o -name "*.TIF" -o -name "*.tiff" -o -name "*.TIFF" \) -mtime -1 | xargs convert -quality 100 \var\tmp\test\{granparentdir}{parentdir}.jp2"
1
Goat Karma

find -execからシェルを実行し、そこでパスを操作します。

find /var/tmp/test -type f \
   \( -name "*.tif" -o -name "*.TIF" -o -name "*.tiff" -o -name "*.TIFF" \) \
   -mtime -1 \
   -exec sh -c '
      for f do
         parent="$(basename "$(dirname "$f")")"
         grandparent="$(basename "$(dirname "$(dirname "$f")")")"
         printf "%s\n" "$grandparent$parent.jp2"
         # convert   -- whatever arguments you want
      done
   ' sh-find {} +

dirnamebasenameを最適ではない方法で使用しました。代わりにシェルパラメータ展開(${f%/*}など)を使用できます。 realpath必要に応じて。

重要なのはシェルを実行し、その中で何でもできるです。

私の例では、シェルコード全体が一重引用符で囲まれています(これは、外側のシェルによる展開が安全でない可能性があるため、内側のシェルが結果を解析するためです)。コード内に一重引用符が必要な場合、適切な引用符はやや複雑になります。この場合、-exec sh -c '…' sh-find {} +の代わりに-exec sh ./script {} +を検討してください。ここで、scriptはコードを含むファイルです。他のシェルスクリプトと同じように、引用するファイル内。

Bashが必要な場合は、-exec bashを使用してください。必要なシェルを使用してください。または、他の何か。 Pythonが必要な場合は、-exec pythonを使用してください。このアプローチは非常に強力です。


詳しくは:

2

これは他の人に役立つかもしれません。コマンドを2つに分割することになりました。

  1. 最初にファイルを変換します
  2. 後で移動/名前を変更する

1。mogrifyを使用した変換

find /var/tmp/test -type f -not -name "*.thumb*" -not -name "*.500x500*" \( -name "*.jpg" -o -name "*.JPG" -o -name "*.png" -o -name "*.PNG" -o -name "*.tif" -o -name "*.TIF" -o -name "*.tiff" -o -name "*.TIFF" -o -name "*.bmp" -o -name "*.BMP" \) | xargs mogrify -format jp2

2。ファイルの名前を変更して選択した場所に移動します

find /var/tmp/test -type f -name "*.jp2" -execdir bash -c \ 'old="{}"; new="$(cd ..; basename -- "$PWD")$(basename -- "$PWD").jp2"; mv "$old" /var/tmp/test/"$new"' - {} \;
1
Goat Karma