ファイルが存在しない場合、Linux シェル oneliner 起動スクリプトは機能しません。

ファイルが存在しない場合、Linux シェル oneliner 起動スクリプトは機能しません。

(png|gif|jpe?g)指定されたフィルタ(!スペースを含むファイル名の問題を回避するには、区切り文字を使用)を持つ指定されたディレクトリ内のすべてのファイルに「最適化された」ファイルがあることを確認\0したいと思います。webpいいえ、変換してください。

私は次の内容を最適化できることを知っていますが、それがうまくいきたいと思います。

より良い解決策がある場合(説明があります!)もちろん面白いです。

IFS= readarray -t -d '' tab < <(find . -type f -print0  | grep -zZE "(png|gif|jpe?g)$") && for f in "${tab[@]}"; do if [ ! -f "$f.webp" ]; then cwebp -q 80 "$f" -o "$f.webp"; fi done

これが私がやっていることです。readarray私のパターンに一致する見つかったすべてのファイルから配列を作成しています。次に、繰り返してファイルが存在するかどうかをテストします。そうでない場合は、cwebp -q 80 "$f" -o "$f.webp";This one not work を呼び出し、次のエラーが発生します。なぜ?

Error! Could not process file ./08/10700_header.jpg
Error! Cannot read input picture file './08/10700_header.jpg'
Error! Could not process file ./08/205790_header.jpg
Error! Cannot read input picture file './08/205790_header.jpg'

ベストアンサー1

Bashのより良い解決策:実際には以下を見つける必要はありません。

shopt -s extglob  # extended pattern match, you likely already have it set
shopt -s globstar # extended directory level search ('**' matches any directory level)

for f in **/*.@(jpg|jpeg|png|gif)
do 
    [[ -f "$f.webp" ]] || cwebp -q 80 "$f" -o "$f.webp"
done

実行するには、parallelすでに完了しているファイルを削除する必要があります直接cwebp呼び出すことができます。 1つの方法は、webpファイルリストを使用してファイルリストをフィルタリングすることです。

printf '%s\n' **/*.@(jpg|jpeg|png|gif) \
    | grep -vf <(printf '%s\n' **/*.webp | sed 's/\.webp$//') \
    | parallel -i cwebp -q 80 {} -o {}.webp

遅い:

  • printf '%s\n' **/*.@(jpg|jpeg|png|gif)可能なすべての候補リストをストリームとして生成します(これはprintf組み込みであるため、bashではコマンドラインにバインドされません)。
  • grep -vf <(printf '%s\n' **/*.webp | sed 's/\.webp$//')このリストからすべての関連ファイルを削除します.webp(ファイルをリストし、*.webp拡張子を切り取り、結果をgrepパターンリストとして使用します)。
  • parallel -i cwebp -q 80 {} -o {}.webp結果を並列実行に提供します。

parallelnullで終わる入力を許可するパラメータがないようですので、奇妙なファイル名がないことを望むだけです。

事前フィルタリング技術は、非並列の状況でも使用できます。

おすすめ記事