Linuxマシンでは、フォルダー階層を走査して、その中のすべての個別のファイル拡張子のリストを取得したいと思います。
これをシェルから実現する最良の方法は何でしょうか?
これを試してください(最良の方法かどうかはわかりませんが、動作します):
find . -type f | Perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u
次のように機能します。
sort
へのパイプは不要で、awkですべて実行できます。
find . -type f | awk -F. '!a[$NF]++{print $NF}'
再帰バージョン:
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort -u
合計が必要な場合(拡張機能が表示された回数):
find . -type f | sed -e 's/.*\.//' | sed -e 's/.*\///' | sort | uniq -c | sort -rn
非再帰的(単一フォルダー):
for f in *.*; do printf "%s\n" "${f##*.}"; done | sort -u
これは このフォーラムの投稿 に基づいています。クレジットはそこにあるはずです。
パワーシェル:
dir -recurse | select-object extension -unique
http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html に感謝
すべてのドットをドットで検索し、接尾辞のみを表示します。
find . -type f -name "*.*" | awk -F. '{print $NF}' | sort -u
すべての接尾辞が3文字であることがわかっている場合
find . -type f -name "*.???" | awk -F. '{print $NF}' | sort -u
または、sedを使用すると、1〜4文字のすべてのサフィックスが表示されます。 {1,4}を、接尾辞に必要な文字の範囲に変更します。
find . -type f | sed -n 's/.*\.\(.\{1,4\}\)$/\1/p'| sort -u
ミックスに独自のバリエーションを追加します。私はそれがロットの中で最も単純で、効率が大きな関心事ではないときに役立つと思います。
find . -type f | grep -o -E '\.[^\.]+$' | sort -u
私のawkレス、sedレス、Perlレス、PythonレスPOSIX準拠の代替:
find . -type f | rev | cut -d. -f1 | rev | tr '[:upper:]' '[:lower:]' | sort | uniq --count | sort -rn
トリックは、最初に行を反転し、拡張子をカットすることです。
また、拡張子を小文字に変換します。
出力例:
3689 jpg
1036 png
610 mp4
90 webm
90 mkv
57 mov
12 avi
10 txt
3 Zip
2 ogv
1 xcf
1 trashinfo
1 sh
1 m4v
1 jpeg
1 ini
1 gqv
1 gcs
1 dv
Pythonでは、空の拡張機能を含む非常に大きなディレクトリにジェネレーターを使用し、各拡張機能が表示される回数を取得します。
import json
import collections
import itertools
import os
root = '/home/andres'
files = itertools.chain.from_iterable((
files for _,_,files in os.walk(root)
))
counter = collections.Counter(
(os.path.splitext(file_)[1] for file_ in files)
)
print json.dumps(counter, indent=2)
ここでたくさんの答えを試してみました。「最良の」答えも試してみました。それらはすべて、私が特に望んでいたものに足りなかった。したがって、複数のプログラムの正規表現コードに過去12時間座って、これらの回答を読んでテストする以外に、これは私が思い通りに動作するものです。
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
ファイル拡張子の数が必要な場合は、以下のコードを使用してください
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort | uniq -c | sort -rn
これらの方法は完了するまでに時間がかかり、おそらく問題を解決する最善の方法ではありませんが、機能します。
更新:@ alpha_989ごとの長いファイル拡張子により問題が発生します。これは、元の正規表現「[[:alpha:]] {3,6}」によるものです。正規表現「[[:alpha:]] {2,16}」を含むように回答を更新しました。ただし、このコードを使用するユーザーは、これらの数値が、最終出力に許可される拡張子の長さの最小値と最大値であることを認識する必要があります。その範囲外のものはすべて、出力で複数の行に分割されます。
注:元の投稿は「-3〜6文字のファイル拡張子のグレープ(ニーズに合わない場合は数字を調整するだけ)。これはキャッシュファイルとシステムファイルを回避するのに役立ちます(システムファイルビットはjailを検索します)。 」
アイデア:特定の長さのファイル拡張子を見つけるために使用できます:
find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{4,}" | awk '{print tolower($0)}' | sort -u
4は、含めるファイル拡張子の長さであり、その長さを超える拡張子も検索します。
Perlを使用する別のソリューションが既にあるので:
Pythonがインストールされている場合は、次のようにすることもできます(シェルから):
python -c "import os;e=set();[[e.add(os.path.splitext(f)[-1]) for f in fn]for _,_,fn in os.walk('/home')];print '\n'.join(e)"
これはまだ言及されていないと思います。
find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
これまでのところ、改行を含むファイル名を適切に処理する返信はありません(これを入力しているときに入ったChristopheDを除きます)。以下はシェルのワンライナーではありませんが、動作し、かなり高速です。
import os, sys
def names(roots):
for root in roots:
for a, b, basenames in os.walk(root):
for basename in basenames:
yield basename
sufs = set(os.path.splitext(x)[1] for x in names(sys.argv[1:]))
for suf in sufs:
if suf:
print suf
最もシンプルで簡単な方法は
for f in *.*; do echo "${f##*.}"; done | sort -u
ChristopheDの3番目の方法で変更されています。
これもできます
find . -type f -name "*.php" -exec PATHTOAPP {} +