it-gundan.com

폴더 계층에서 고유 한 파일 확장자를 모두 찾으려면 어떻게해야합니까?

Linux 컴퓨터에서 폴더 계층 구조를 탐색하고 그 안에있는 모든 고유 파일 확장자 목록을 얻고 싶습니다.

쉘에서 이것을 달성하는 가장 좋은 방법은 무엇입니까?

207
GloryFish

이것을 시도하십시오 (최상의 방법인지 확실하지 않지만 작동합니다).

find . -type f | Perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u

다음과 같이 작동합니다.

  • 현재 폴더에서 모든 파일 찾기
  • 파일 확장명을 인쇄합니다 (있는 경우)
  • 고유 한 정렬 된 목록 만들기
312
Ivan Nevostruev

sort에 파이프가 필요하지 않습니다. awk가 모든 작업을 수행 할 수 있습니다.

find . -type f | awk -F. '!a[$NF]++{print $NF}'
45
SiegeX

재귀 버전 :

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

나는 이것을 기반으로 이 포럼 게시물 , 신용이 있어야합니다.

34
ChristopheD

파워 쉘 :

dir -recurse | select-object extension -unique

덕분에 http://kevin-berridge.blogspot.com/2007/11/windows-powershell.html

23
Simon R

점이있는 모든 것을 찾고 접미사 만 표시하십시오.

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
12
user224243

믹스에 내 변형을 추가합니다. 나는 그것이 가장 단순하고 효율성이 큰 관심사가 아닐 때 유용 할 수 있다고 생각합니다.

find . -type f | grep -o -E '\.[^\.]+$' | sort -u
7
gkb0986

나의 awk-less, sed-less, Perl-less, Python-less 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
6
Ondra Žižka

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)
5
Andres Restrepo

나는 여기에 많은 답변을 시도했다. 심지어 "최상의"답변까지. 그들은 모두 내가 구체적으로 추구 한 것보다 부족했습니다. 따라서 지난 12 시간 동안 여러 프로그램에 대한 정규식 코드에 앉아 이러한 답변을 읽고 테스트 한 결과 이것이 내가 원하는 것처럼 정확하게 작동했습니다.

 find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{2,16}" | awk '{print tolower($0)}' | sort -u
  • 확장자가있는 모든 파일을 찾습니다.
  • 확장 만 그립
  • 2 ~ 16 자 사이의 파일 확장자를 잡으십시오 (필요에 맞지 않으면 숫자를 조정하십시오). 캐시 파일 및 시스템 파일을 피할 수 있습니다 (시스템 파일 비트는 감옥을 검색하는 것임).
  • 확장 프로그램을 소문자로 인쇄하십시오.
  • 고유 한 값만 정렬하고 가져옵니다. 원래 나는 awk 대답을 시도했지만 대소 문자 구분이 다양한 두 번 인쇄 된 항목을 만들 것입니다.

파일 확장자가 필요한 경우 아래 코드를 사용하십시오.

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 자 사이의 파일 확장자에 대한 Greps를 읽었습니다 (필요에 맞지 않으면 숫자를 조정하십시오). 캐시 파일 및 시스템 파일을 피하는 데 도움이됩니다 (시스템 파일 비트는 감옥을 검색하는 것임). "

아이디어 : 다음을 통해 특정 길이의 파일 확장자를 찾는 데 사용할 수 있습니다.

 find . -type f -name "*.*" | grep -o -E "\.[^\.]+$" | grep -o -E "[[:alpha:]]{4,}" | awk '{print tolower($0)}' | sort -u

여기서 4는 포함 할 파일 확장자 길이이며 해당 길이 이상의 확장자를 찾습니다.

5
Shinrai

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)"
3
ChristopheD

나는 이것이 아직 언급되지 않았다고 생각한다.

find . -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
2
Dmitry B.

지금까지 답글은 개행 문자가있는 파일 이름을 올바르게 처리하지 못했습니다 (ChristopheD는 제외하고 입력했습니다). 다음은 Shell one-liner가 아니지만 작동하며 합리적으로 빠릅니다.

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
2
user25148

가장 간단하고 간단한 방법은

for f in *.*; do echo "${f##*.}"; done | sort -u

ChristopheD의 세 번째 방법으로 수정되었습니다.

1
Robert

당신은 또한 이것을 할 수 있습니다

find . -type f -name "*.php" -exec PATHTOAPP {} +
0
jrock2004