次の名前のディレクトリにイメージセットがある場合:
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[@]}"
シェルでは、zsh
globbing自体で名前をテストできます。*.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
空のボール 設定されている場合、Bash はファイルと一致しないファイル名パターンを、
自分ではなく空の文字列に拡張できるようにします。