私はさまざまな歴史的理由で私のシステム全体に散らばっている写真を整理しようとしています。これを開始するために、コマンドラインを使用して1つ以上のjpgファイルを含むすべてのディレクトリのリストを作成しようとしました。他の画像ファイル形式を見つけることを心配する必要はありませんが、jpgが大文字と小文字で表示されることを許可する必要があります。
各ディレクトリ名が最終リストに一度だけ現れることを望みます。たとえば、次のディレクトリがある場合、各ディレクトリには1つ以上のjpgまたはJPGファイルが含まれます。
~Mike/Pictures
~Mike/Pictures/London/Olympics
~Mike/Pictures/London
~Mike/Pictures/London/Holiday
~Mike/Photos
~Mike/Family History/Swaine
結果がディレクトリごとに一度だけ一覧表示されます。含まれる画像ファイルの数に関係なく、最初に並べ替えてからファイルに書き込むことをお勧めします。
~Mike/Family History/Swaine
~Mike/Photos
~Mike/Pictures
~Mike/Pictures/London
~Mike/Pictures/London/Holiday
~Mike/Pictures/London/Olympics
私のコマンドライン技術はまだこのレベルに達していません!いくつかの単純な形式の個々のコマンドを使用できますが、一度複雑になったりパイプを接続したりすると、問題が発生する傾向があります。
ベストアンサー1
JPEG画像ファイルのサフィックスは、.jpg
または次のように見なされます.JPG
。
find "$HOME" -type f \( -name '*.jpg' -o -name '*.JPG' \) \
-exec sh -c 'for d; do dirname "$d"; done' sh {} + | sort -u -o jpeg_dirs.txt
これは、改行文字を含むファンキーなディレクトリ名がないことに依存します。
GNUの使用find
:
find "$HOME" -type f \( -name '*.jpg' -o -name '*.JPG' \) -printf '%h\n' | sort -u -o jpeg_dirs.txt
このfind
コマンドは、ホームディレクトリ内のすべてのJPEGイメージを検索し、そのイメージがあるディレクトリの名前を印刷します。このディレクトリ名のリストを取得してsort -u
並べ替え、重複エントリを削除します。結果はjpeg_dirs.txt
現在のディレクトリのファイルに書き込まれます。
2021年初め(3.3年後)にこれを振り返ってみると、上記の解決策はそれ自体は間違っているわけではありませんが、少し逆さまになったので少し煩わされます。また、「良いファイル名」(改行なし)について明らかな仮定をします。
find
ディレクトリを検索するときは、上記のように通常のファイルを検索しないでください。ディレクトリが存在する場合は、各ディレクトリを調べて、一致するファイルがあるかどうか、または*.jpg
他*.JPG
のファイル名のサフィックスが簡単に追加されることを確認できます。
find "$HOME" -type d -exec bash -O nullglob -O dotglob -O extglob -c '
for dirpath do
set -- "$dirpath"/*.@(jpg|JPG)
[ "$#" -eq 0 ] || printf "%s\n" "$dirpath"
done' bash {} +
これはホームディレクトリの下に各ディレクトリを見て、*.@(jpg|JPG)
各ディレクトリのワイルドカードパターンを拡張しようとします。このパターンは2つの別々のパターンで作成することも、*.jpg
私*.JPG
たちが探しているすべてのファイルと一致させることもできます。名前が一致した場合、これは出力したい名前のディレクトリであると仮定します。これは、以下を含むディレクトリに対して誤検出を提供します。サブディレクトリこの接尾辞として。
内部スクリプトを実行するために私たちが持っているシェルオプションを使用すると、隠された名前をbash
一致させることができ(dotglob
)、拡張されていないままの代わりに何も一致しないときにglobbingパターンが完全に消えることを許可し(nullglob
)、ksh
-inspiredを使用してglobbingパターンを拡張できます@(...|...)
。
zsh
シェルの使用:
typeset -U list=(~/**/*.(jpg|JPG)(.DN:h))
print -rC1 $list
list
これにより、一意の要素のみを格納する属性を持つ配列変数が作成されます。拡張ファイル名はワイルドカードパターンの結果として初期化されます。このパターンはホームディレクトリまたはその下のすべてのJPEG画像ファイルと一致し、:h
最後のパターンは生成されたパス名から実際のファイル名を削除します。.
パターンが通常のファイルにのみ一致するようにしますD
。N
dotglob
nullglob
bash