Jak wyświetlić typ pliku za pomocą ls?

12

Nie wiem, czy lsjest w stanie wyświetlić kolumnę typu pliku.

Szybkie wyszukiwanie online i wyszukiwanie mannie ujawniło takiej możliwości. Czy jest w stanie to zrobić?

Wyjaśnienie: Jest to szczególnie przydatne, jeśli pliki nie mają rozszerzenia.

Aktualizacja

Na dzień 28.04.2018 odpowiedzi były dość interesujące, ale nie zawierały tego, czego szukałem. Dokładniej,

  • filepodaje rzeczywiste typy plików, ale nie integruje się dobrze ls. W szczególności używamls -lhtrpG --group-directories-first --color=always

  • ls -Fjest lsrozwiązaniem, jednak zapewnia symbole, a nie kolumnę rzeczywistych typów plików.

Z tego powodu nie zaznaczyłem żadnej odpowiedzi jako odpowiedzi, której szukam.

użytkownik10853
źródło
powiązane informacje: dla czytelnego dla człowieka: ls -lahtrpF --group-directories-first --color=always /devlub ls -lsahG /dev, i dla czytelnego dla programu ls -lsa /dev. szczegóły w man lsdokumentacji.
user1742529

Odpowiedzi:

16

fileto zdecydowanie właściwy wybór, aby uzyskać żądane informacje o typie pliku. Aby połączyć wyniki z wynikami lssugeruję użycie find:

find -maxdepth 1 -type f -ls -exec file -b {} \;

Znajduje każdy plik w bieżącym katalogu i wypisuje dane wyjściowe, ls -dilsjak również dane wyjściowe file -b, każdy w osobnym wierszu. Przykładowe dane wyjściowe:

  2757145      4 -rw-rw-r--   1 dessert dessert      914 Apr 26 14:02 ./some.html
HTML document, ASCII text
  2757135      4 -rw-rw-r--   1 dessert dessert      201 Apr 13 15:26 ./a_text_file
UTF-8 Unicode text, with CRLF, LF line terminators

Ale ponieważ nie chcesz linii typu pliku , a raczej kolumny typu pliku , oto sposób na pozbycie się znaku nowej linii między wierszami:

find -maxdepth 1 -type f -exec sh -c "ls -l {} | tr '\n' '\t'; file -b {}" \;

Przykładowe dane wyjściowe:

-rw-rw-r-- 1 dessert dessert 914 Apr 26 14:02 ./some.html    HTML document, ASCII text
-rw-rw-r-- 1 dessert dessert 201 Apr 13 15:26 ./a_text_file  UTF-8 Unicode text, with CRLF, LF line terminators

Ta nowa kolumna jest dość długa, więc odetnijmy wszystko od pierwszego przecinka:

find -maxdepth 1 -type f -exec sh -c "ls -l {} | tr '\n' '\t'; file -b {} | cut -d, -f1" \;

Wynik tego wygląda następująco:

-rw-rw-r-- 1 dessert dessert 914 Apr 26 14:02 ./some.html    HTML document
-rw-rw-r-- 1 dessert dessert 201 Apr 13 15:26 ./a_text_file  UTF-8 Unicode text

To nie jest całkiem przydatne, więc co powiesz na alias? W poniższym wierszu w ~/.bash_aliasespliku wystarczy uruchomić, lsfaby uzyskać powyższe dane wyjściowe dla bieżącego katalogu.

alias lsf='find -maxdepth 1 -type f -exec sh -c "ls -l {} | tr '"'\n'"' '"'\t'"'; file -b {} | cut -d, -f1" \;'
deser
źródło
1
Jeśli użyjesz funkcji zamiast aliasu, będzie to mniej cytat, a jeśli użyjesz pastelub column, możesz uzyskać lepsze wyrównanie: lsf () { find -maxdepth 1 -type f -exec bash -c 'column <(ls -l "$@") <(file -b "$@" | cut -d, -f1)' _ {} + ; }Problem wyrównania nie jest widoczny w odpowiedzi z powodu podobnych rozmiarów i dat. (Będzie to również nieco szybsze, ponieważ polecenia będą wywoływane mniej razy zamiast raz na plik.)
muru 27.04.18
@muru Dzięki za wiele dobrych sugestii! Czy to columnpodejście działa dla Ciebie? Po prostu wypisuje dane wyjściowe ls -ldla każdego pliku, a następnie filedane wyjściowe dla każdego pliku dla mnie, tak jakby powłoka po prostu zrobiła ls -l "$@"; file -b "$@" | cut -d, -f1
deser
To robi. paste.ubuntu.com/p/KjPthXPDPb - górna część pochodzi z aliasu, a dolna część jest funkcją, obie uruchamiane z /etc.
mur
Wydaje mi się, że widzę problem - jeśli columndane wyjściowe nie są wysyłane do terminala, musisz określić liczbę kolumn lub wyśle ​​pliki jeden po drugim; więc column -c "$COLUMNS" ...powinno działać w obu przypadkach.
mur
Uruchamiasz (przynajmniej?) 5 procesów dla każdego pliku, więc prawdopodobnie będzie to powolne, gdy w katalogu będzie dużo plików…
JanC
10

Myślę, że najlepszym sposobem wyświetlenia typu pliku jest użycie tego polecenia:

file <filename>

Jeśli chcesz wyświetlić listę typów wszystkich plików w katalogu, użyj:

file *

<code> plik * </code> próbka z mojego komputera

Aby uzyskać więcej informacji na temat argumentów, zobacz:

man file
singrium
źródło
Chociaż odpowiedź ta nie odpowiada bezpośrednio na pytanie PO, pokazuje prawidłowy sposób znalezienia typu pliku MIME i powinna zostać oznaczona jako poprawna odpowiedź. Aby uzyskać mime typetylko za pomocą: file --mime-type filename.
Pedro Lobito,
@PedroLobito Myślę, że ściśle powiązane pytanie obejmuje filecałkiem dobrze, ale to pytanie jest inne.
deser
Głosuję za odpowiedzią, biorąc pod uwagę, że jako pierwszy udzieliłeś fileodpowiedzi. Gdy odpowiedziałem innym, to nie wystarcza (musi być zintegrowane z ls), więc głosuję dalej. Dziękuję Ci.
user10853,
1
plik * jest najlepszą odpowiedzią
tramada
1
file --mime /dev/*dla listy mimów w katalogu / dev zamiast bieżącej
użytkownik1742529
7

Dla jasności zamierzam wskazać, że można zobaczyć typ pliku w podstawowym sensie za lspomocą -Fflagi (klasyfikuj), która dołącza symbol do nazwy pliku w zależności od jego typu:

‘-F’
‘--classify’
‘--indicator-style=classify’
     Append a character to each file name indicating the file type.
     Also, for regular files that are executable, append ‘*’.  The file
     type indicators are ‘/’ for directories, ‘@’ for symbolic links,
     ‘|’ for FIFOs, ‘=’ for sockets, ‘>’ for doors, and nothing for
     regular files.

Możesz jednak zobaczyć te informacje nieco mniej zaszyfrowane wyświetlane w pierwszej literze wyniku ls -l. Odpowiedź wjandrea opisuje to bardziej szczegółowo.

Ale nie sądzę, że to właśnie rozumiesz przez typ pliku. lsKomenda nie wygląda wewnątrz regularne plików - tylko na listach katalogów (które przechowują nazwy plików) i-węzłów (których metadane sklep, w tym „typu” w sensie wspomniano wcześniej).

Tak więc lspolecenie nie może wyświetlić typu pliku w sensie, czy jest to obraz JPG, plik binarny, plik tekstowy lub dokument LibreOffice, ponieważ nie ma tych informacji.

W tym celu, jak wskazuje odpowiedź singrium , potrzebujesz filepolecenia, które sprawdza około 50-100 kB zawartości plików, aby określić ich typ.

Zanna
źródło
@Zana Dziękuję za zwrócenie mojej uwagi na tę flagę. Zrobiłoby to na razie, chociaż nie tego szukałem (rzeczywiste typy plików). Zagłosuję za to.
user10853
3

Jedną z form typu pliku jest to, czy plik jest zwykłym plikiem, katalogiem, urządzeniem, dowiązaniem symbolicznym itp. lsMoże to pokazać za pomocą opcji -llub -F.

  • Opcja -lpokaże typ pliku jako pojedynczy znak na początku listy, np .:

    $ ls -l
    drwxrwxr-x 2 user user 4096 Dec 11 00:18 DIR
    -rw-rw-r-- 1 user user    0 Dec 11 00:18 FILE
    lrwxrwxrwx 1 user user    4 Dec 11 00:19 LINK -> FILE
    

    Gdzie -jest zwykły plik, djest katalogiem i ljest dowiązaniem symbolicznym.

  • Opcja -Fwyświetli typ pliku jako sufiks, np .:

    $ ls -F
    DIR/ FILE LINK@
    

    Gdzie żaden przyrostek nie jest zwykłym plikiem, /jest katalogiem i @dowiązaniem symbolicznym.

Więcej informacji na ten temat można znaleźć info coreutils 'ls invocation'tutaj:

Dla -l:

‘-’ regular file
‘b’ block special file
‘c’ character special file
‘C’ high performance (“contiguous data”) file
‘d’ directory
‘D’ door (Solaris 2.5 and up)
‘l’ symbolic link
‘M’ off-line (“migrated”) file (Cray DMF)
‘n’ network special file (HP-UX)
‘p’ FIFO (named pipe)
‘P’ port (Solaris 10 and up)
‘s’ socket
‘?’ some other file type

Dla -F:

nothing for regular files
‘*’ regular files that are executable
‘/’ directories
‘@’ symbolic links
‘|’ FIFOs
‘=’ sockets
‘>’ doors
wjandrea
źródło