失われたファイルを検索する方法が必要です

失われたファイルを検索する方法が必要です

次の名前のディレクトリにイメージセットがある場合:

filename.jpg
filename.jpg.webp

filename-150x150.jpg

filename-250x250.jpg
filename-250x250.jpg.webp

filename-600x600.jpg

filename-800x800.jpg
filename-800x800.jpg.webp

findバージョンなしですべてのファイルを返すためにコマンド(または他のコマンド)を使用する方法はありますか.webp?したがって、この例では 150x150 および 600x600 ファイルを返します。

答え1

さまざまなバリアントで見つかった次のファイル名のいずれかを使用する場合は、次の点を確認してください。出力のファイル名は解析されません。。代わりに、printfあなたがすべきことに置き換えてください。これにより、スペースとワイルドカードを含むファイル名に関する問題を回避できます。また、コードをより効率的で美しくし、最終的にはより健康的なライフスタイルとより良い友達につながります。

バラより検索結果を繰り返すのはなぜ悪い習慣ですか?

.webp私が作成した仮定の1つは、そのファイルを作成しようとしているので、そのファイルがないJPEG画像を探したいということです.webp。これが、(「名前が存在し、通常のファイルであるか、そのファイルへのシンボリックリンクです」)または(「名前が存在して読み取ることができます」)テストではなく、以下の(「-e名前が存在します」)テストを使用する理由です。 。-f-r

.webp名前があれば存在する、ディレクトリ、文字特殊ファイル、またはその他の異なるファイルタイプの場合(テストは次のようになります)-f間違った)または読み取れない場合(テストが-r間違っている場合)、ファイルの方法.webpによっては、既存のコンテンツを上書きしたり、ディレクトリに入れたり、権限エラーが発生したりするため、ファイルの生成に問題が発生します。.webp創造。


単純なループを使用して一致する名前を繰り返し、*.jpgファイルに対応しない名前を印刷します*.jpg.webp

for name in *.jpg; do
    [ -f "$name" ] && [ ! -e "$name.webp" ] && printf '%s\n' "$name"
done

リストに名前を保存するには、位置引数リストを使用できます。

set --
for name in *.jpg; do
    [ -f "$name" ] && [ ! -e "$name.webp" ] && set -- "$@" "$name"
done

printf 'Needs webp fixed: %s\n' "$@"

では、bash名前付き配列に名前を保存できます。

needs_webp=()
for name in *.jpg; do
    [ -f "$name" ] && [ ! -e "$name.webp" ] && needs_webp+=( "$name" )
done

printf 'Needs webp fixed: %s\n' "${needs_webp[@]}"

シェルでは、zshglobbing自体で名前をテストできます。*.webp

printf 'Needs webp fixed: %s\n' *.jpg(.e['[ ! -e $REPLY.webp ]'])

ここで.、パターンの末尾にあるワイルドカード修飾子は、(ディレクトリなどではない)一般ファイルのみが一致していることを確認し、現在の名前を結果リストに含める必要があることをe['[ ! -e $REPLY.webp ]']確認するテストとして機能します。$REPLY


そしてfind

find . -name '*.jpg' -type f ! -exec test -e {}.webp \; -print

現在のディレクトリまたは下のディレクトリでパターンと一致する名前を持つ一般的なファイルを探し、同じ名前に対応するが最後に追加されたファイルが*.jpgない場合は、その名前を印刷します。.webp

{}ただし、POSIX標準が他の文字列に関連付けられている場合(上記のように)、POSIX標準はその文字列が現在のファイル名に置き換えられることを保証しません。だからそれがうまくいくかどうかを確認したい場合は、次のように言います。

find . -name '*.jpg' -type f -exec sh -c '
    for name do
        [ -e "$name.webp" ] && printf "%s\n" "$name"
    done' {} +

ご覧のとおり、今回はこの回答の最初のループにある程度戻ってきました。唯一の違いは、find現在のディレクトリまたはそのサブディレクトリから再帰的に既存のパス名を提供することです。

答え2

これは私にとって効果的です。

find . -not -name '*.webp' -exec test ! -r {}.webp \; -exec echo {} \;

で終わらないすべての名前を見つけます.webp。見つかった名前ごとに、.webp同じ名前と拡張子を持つファイルが存在するかどうかをテストします。そうでない場合は、ファイルを印刷します。

2つ目は、-exec最初のものが正常に返された場合、つまり対応する.webp拡張ファイルが存在しない場合にのみ実行されることは注目に値します。

ファイルリストを実行すると、私の出力は次のようになります。

./filename-600x600.jpg
./filename-150x150.jpg

答え3

ループを使って次のことを試してください。

# to expand to null string in empty directories¹
shopt -s nullglob
# loop over the jpg files
for i in *.jpg; do 
  # test if there's a file that matches the name but with '.webp' extension
  # if there's a match don't do anything and continue with the loop
 [[ -f "$i.webp" ]] && continue || \
 # else perform an operation
 echo "$i"
done

filename-150x150.jpg
filename-600x600.jpg

^4.3.2 組み込み店舗

空のボール

    設定されている場合、Bash はファイルと一致しないファイル名パターンを、   
自分ではなく空の文字列に拡張できるようにします。

関連情報