Jak znaleźć pliki według typu?

Wiem, że mogę znaleźć pliki za pomocą find: find . -type f -name "sunrise" . Przykładowy wynik:

./sunrise ./events/sunrise ./astronomy/sunrise ./schedule/sunrise 

Wiem również, że mogę określić typ pliku: file sunrise. Przykładowy wynik:

sunrise: PEM RSA private key 

Ale jak mogę znaleźć pliki według typu?

Na przykład my-find . -type f -name "sunrise" -filetype=bash-script:

./astronomy/sunrise ./schedule/sunrise 

Komentarze

  • Brak --filetype dla polecenia find lub cokolwiek innego, co powie ci typ pliku. Jedyne, co możesz zrobić, to użyć --exec file {} \;, a następnie przesłać go do grep Bourne, jeśli szukasz skryptów bash lub jeśli szukałeś skryptów Perla lub czegoś podobnego.

Odpowiedz

„Typy plików” w systemie Unix to takie rzeczy, jak zwykłe pliki, katalogi, nazwane potoki, specjalne pliki znakowe, dowiązania symboliczne itp. Są to typy pliki, które find mogą filtrować za pomocą opcji -type.

find nie może samodzielnie rozróżnić między „skryptem powłoki”, „plikiem obrazu JPEG” ani jakimkolwiek innym typem zwykłego pliku . Te typy danych można jednak rozróżnić za pomocą narzędzia file, które sprawdza poszczególne sygnatury w samych plikach, aby określić ich typ.

Typowy sposób oznaczania różne typy plików danych to typ MIME , a file jest w stanie określić typ MIME plik.


Używanie file z find do wykrywania typu MIME zwykłych plików i użyj tego aby znaleźć tylko skrypty powłoki:

find . -type f -exec sh -c " case $( file -bi "$1" ) in */x-shellscript*) exit 0 esac exit 1" sh {} ";" -print 

lub używając bash,

find . -type f \ -exec bash -c "[[ "$( file -bi "$1" )" == */x-shellscript* ]]" bash {} ";" \ -print 

Dodaj -name sunrise przed -exec, jeśli chcesz wykrywać tylko skrypty o tej nazwie.

Polecenie find powyżej znajdzie wszystkie zwykłe pliki w bieżącym katalogu lub poniżej, a dla każdego takiego pliku wywołaj krótki wbudowany skrypt powłoki. Ten skrypt uruchamia file -bi na znalezionym pliku i kończy pracę z zerowym kodem zakończenia, jeśli dane wyjściowe tego polecenia zawierają ciąg /x-shellscript. Jeśli wynik nie zawiera tego ciągu, kończy się z niezerowym kodem zakończenia, co powoduje, że find natychmiast przechodzi do następnego pliku. Jeśli okaże się, że plik jest skryptem powłoki, polecenie find przejdzie do wyprowadzenia nazwy ścieżki pliku (-print w end, który można również zastąpić inną czynnością).

Polecenie file -bi wyświetli typ MIME pliku. W przypadku skryptu powłoki w systemie Linux ( i większości innych systemów), byłoby to coś w rodzaju

text/x-shellscript; charset=us-ascii 

w systemach z nieco starszym wariantem file, może to być

application/x-shellscript 

Wspólnym bitem jest podciąg /x-shellscript.

Pamiętaj, że w systemie macOS musiałbyś użyć file -bI zamiast file -bi z powodów ( -i robi coś zupełnie innego). Dane wyjściowe w systemie MacOS są podobne do tych z systemu Linux.


Czy chcesz wykonać jakąś niestandardową akcję na każdym znalezionym skrypcie powłoki możesz zrobić th z innym -exec zamiast -print w find poleceniach powyżej, ale byłoby również możliwe wykonanie

find . -type f -exec sh -c " for pathname do case $( file -bi "$pathname" ) in */x-shellscript*) ;; *) continue esac # some code here that acts on "$pathname" done" sh {} + 

lub, z bash,

find . -type f -exec bash -c " for pathname do [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue # some code here that acts on "$pathname" done" bash {} + 

Powiązane:

Odpowiedź

Możesz wykonać find na każdym znalezionym pliku a następnie grep dla wyniku, który Cię „interesuje”.

# When looking for ASCII Text find . -type -exec file {} \; | grep "ASCII" # or for MS Word Documents find . -type f -exec file {} \; | grep "Microsoft Word" 

Proponuję, aby wzorzec wyszukiwania był jak najbardziej zbliżony do oczekiwanego zachowania liczby liczba fałszywie dodatnich wyników jest niska.

Uważaj, pliki ze znakami nowej linii w nazwach mogą powodować problemy z tym podejściem.

Odpowiedź

Korzystanie z modułu perl” s File::LibMagic:

perl -MFile::LibMagic=:easy -MFile::Find -le " find sub { print $File::Find::name if $_ eq "sunrise" and -f and MagicFile$_ eq "PEM RSA private key" }, @ARGV" -- . 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *