他の拡張子と一致しない1つの拡張子を持つファイル名を見つける

他の拡張子と一致しない1つの拡張子を持つファイル名を見つける

画像を独自の画像形式で保存する特別なデジタルカメラを購入しました.lri。会社には、.lriファイルを標準のjpgファイルとdngファイルにレンダリングできるデスクトッププログラムがあります。

このファイルが保存されているディレクトリを見て、いくつかのファイル変換が見つからないことがわかりました。しかし、欠落しているファイルのペア、ファイル番号、および入れ子になったディレクトリ構造を視覚的に確認することができたため、変換したいすべてのファイルを確実に見つけることは困難でした。

.lri一致するファイル名がない場合は、拡張子を持つファイルを見つけるためのシェルコマンドを探しています.dng(現在のjpgファイルは心配しません)。たとえば、私が数ヶ月または数年前に勤勉に働いた場合は、そうでなければなりませL16_04198.lriんでした。L16_04198.dng

編集する私が言及していない2つの制限は、ファイルが入れ子になったディレクトリ構造にあるため、再帰検索が必要であることです。また、私のディレクトリ名にはスペースが含まれているため、これを処理できる必要があります。

L16_04198.lriしたがって、入れ子になったサブディレクトリ構造でファイル名が見つからない場合は、ファイル名を報告するコマンドまたはスクリプトが必要ですL16_04198.dng(ファイルをレンダリングしたが間違ったサブディレクトリに入れた可能性があります)。

コマンドに精通していますfindが、「非」ファイル名を見つけて見つからなかった場合に報告する方法がわかりません。

答え1

次のことを試すことができます。

shopt -s globstar
for f in **/*.lri; do 
  [[ ! $(find . -name "$(basename "${f%%.lri}").dng") ]] && realpath "$f"
done

答え2

簡単に言うと:

find . -name "*.txt" | perl -nle 's/\.txt$/.foo/; print unless -e' | cat -v

Perlを使った例は次のとおりです。

c.fooがありません。

$ ls
a.foo  a.txt  b.foo  b.txt  c.txt

私たちはこれをこのように見つけることができます

$ ls *.txt | perl -nle 's/\.txt$/.foo/; print unless -e '
c.foo

c.fooがありません


更新:メタ文字などを含むファイル名の処理

スペース、改行、およびパイプ記号を含むファイル名のセットを検討してください。

$ ls *txt
 a.txt   b.txt   c.txt  'd d.txt'  'e'$'\r''e.txt'  'f'$'\n''f.txt'  'g|g.txt'   taskmaster.txt

実際、Perlはlsの出力を解析するのに何の問題もないようです。

$ ls *txt | perl -nle 's/\.txt$/.foo/; print unless -e'
c.foo
d d.foo
e.foo
f
f.foo
g|g.foo
taskmaster.foo

明らかに、ファイル名に制御文字が含まれている場合は、より明確にしたいかもしれません。

$ ls *txt | perl -nle 's/\.txt$/.foo/; print unless -e' | cat -v
c.foo
d d.foo
e^Me.foo
f
f.foo
g|g.foo
taskmaster.foo

再帰的に機能したい場合

$ find . -name "*.txt" | perl -nle 's/\.txt$/.foo/; print unless -e' | cat -v
./c.foo
./d d.foo
./e^Me.foo
./f
f.foo
./g|g.foo
./h*h.foo
./temp/j.foo

関連情報