アルカナが見つかりました: -exec ラインでパイプを動作させることはできません

アルカナが見つかりました: -exec ラインでパイプを動作させることはできません

sedを介して検索結果をxformストリームにパイプし、変換されたストリームをスクリプトの2つの引数のいずれかに使用するにはどうすればよいですか?つまり:

探すfile1.tiff(およびその他のファイル)が表示されます。
sedfile1.tiff --> file1.jpgを変換し
、次の2つのパラメータを使用してコマンドを実行します。file1.tiff file1.jpg 変換

いくつかの方法を試しましたが、取得できません。風味を加えようとする試みは次のとおりです。

find ./out -regex ".*_p[bg]_.*tiff" -exec echo "Processing {}" \; -exec convert {} `echo {} | sed s/tiff/jpg/` \;

このような部分を別にしようと諦めてPythonスクリプトを作成しなければならなかったが、結局Unixツールを学ぼうとしたが、今はすっかり抜けています。助ける!

答え1

そこにパイプがあるかどうかはわかりません-execfind -exec echo {} \| sed s/tiff/jpg \;うまくいかないようです。

最良のオプションは、変換を実行するスクリプトを作成することです。

変換_tiff_to_jpg:

#!/bin/bash
echo "Processing $1"
convert "$1" "${1/%tiff/jpg}"

find -exec期待どおりに呼び出してください。

find ./out -regex ".*_p[bg]_.*tiff" -exec convert_tiff_to_jpg {} \;

これを行うために使用できる多くの方法がありますが、find -print0 | xargs -0すべて非常に見苦しいです。

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
while IFS= read -d $'\0' -r filename; do
    echo "Processing $filename"
    convert "$filename" "$(echo "$filename" | sed 's/tiff$/jpg/')"
done

または

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
while IFS= read -d $'\0' -r filename; do
    echo "Processing $filename"
    convert "$filename" "${filename/%tiff/jpg}"
done

または

find ./out -regex ".*_p[bg]_.*tiff" -print0 |
    xargs -0 -I FILE bash -c 'F="FILE"; echo "$F" "${F/%tiff/jpg}"'

ちなみに、ファイル名の終わり以外の場所に表示された場合は変更しないようにs/tiff/jpg変更しました。s/tiff$/jpgtiff

答え2

にシェルコマンドを渡すには、-execプログラム名とパラメータのリストが必要です。したがって、シェルを起動するように明示的に指示する必要があります。

find ./out -regex ".*_p[bg]_.*tiff" \
     -exec sh -c 'echo "Processing $0"; convert "$0" "${0%.tiff}.jpg"' {} \;
  • sh -c 'shell code, not using single quotes'これは、引数付きのコマンドのコンテキストでシェル機能が必要な場合に比較的一般的な慣用語です。
  • -exec sh -c 'do stuff with "$0"' {} \;findシェルに関連する慣用的な表現です。一部のバージョンの find では、{}シェルコードに直接書き込むことができますが、これは悪い考えです。一部のバージョンの find ではこれを許可しないだけでなく、ファイル名に特殊文字 (引用符など) が含まれていると混乱を招く可能性があるためです。したがって、ファイル名はゼロ番目の引数としてシェルに渡され、スクリプトはシェル変数を使用して$0ファイルを参照します。
  • echo tiff_filename | sed s/tiff/jpg/ファイル名を変更する複雑で非効率的で不正確で脆弱な方法です。 sedを呼び出すので、複雑で非効率的です。tiffファイルのどこにでも置き換えようとしているので、これは間違っています。たとえばtiffany.tiff、一部のファイル名(一部のマングルバックスラッシュ実装)jpgany.tiffでは機能しないため、脆弱です。echo代わりに、ファイル名からサフィックスを${0%.tiff}削除してください。.tiff$0

関連情報