Как отобразить тип файла с помощью ls?

12

Я не знаю, lsспособен ли отображать столбец типа файла.

Выполнение быстрого онлайн-поиска и поиска manне выявило такой возможности. Это способно сделать это?

Пояснение: это особенно полезно, если файлы не имеют расширения.

Обновить

По состоянию на 2018-04-28 ответы были довольно интересными, однако они не дали того, что я искал. Более конкретно,

  • fileдействительно дает фактические типы файлов, но они плохо интегрируются с ls. В частности, я используюls -lhtrpG --group-directories-first --color=always

  • ls -FЭто lsрешение, однако оно предоставляет символы, а не столбцы фактических типов файлов.

По этой причине я не отметил ни один из ответов как ответ, который я ищу.

user10853
источник
связанная информация: для человека, читаемого: ls -lahtrpF --group-directories-first --color=always /devили ls -lsahG /dev, и для программы, читаемой ls -lsa /dev. см. man lsдокументацию для деталей.
user1742529

Ответы:

16

fileбезусловно, правильный выбор, чтобы получить информацию о типе файла, который вы хотите. Чтобы объединить его результаты с результатами, lsя предлагаю использовать find:

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

Это находит каждый файл в текущем каталоге и печатает вывод, ls -dilsа также вывод file -bдля него, каждый в отдельной строке. Пример вывода:

  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

Но, поскольку вам нужна не строка типа файла, а столбец типа файла , вот способ избавиться от символа новой строки между строками:

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

Пример вывода:

-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

Этот новый столбец довольно длинный, поэтому давайте вырезать все из первой запятой:

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

Результат этого выглядит так:

-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

Это не совсем удобно, так как насчет alias? Со следующей строкой в ​​вашем ~/.bash_aliasesфайле вам просто нужно запустить, lsfчтобы получить вышеуказанный вывод для текущего каталога.

alias lsf='find -maxdepth 1 -type f -exec sh -c "ls -l {} | tr '"'\n'"' '"'\t'"'; file -b {} | cut -d, -f1" \;'
Десерт
источник
1
Если вы используете функцию вместо псевдонима, это будет меньше адского цитирования, и если вы используете pasteили column, вы можете получить лучшее выравнивание: lsf () { find -maxdepth 1 -type f -exec bash -c 'column <(ls -l "$@") <(file -b "$@" | cut -d, -f1)' _ {} + ; }проблема выравнивания не очевидна в ответе из-за схожих размеров и дат. (Это также будет немного быстрее, так как команды будут вызываться меньше раз, чем один раз для каждого файла.)
muru
@muru Спасибо за много хороших предложений! Этот columnподход работает для вас? Он просто печатает вывод ls -lдля каждого файла с последующим fileвыводом для каждого файла для меня, как если бы оболочка просто делала ls -l "$@"; file -b "$@" | cut -d, -f1
десерт
Оно делает. paste.ubuntu.com/p/KjPthXPDPb - верхняя часть - из псевдонима, а нижняя - из функции, обе из которых запускаются /etc.
Муру
Я думаю, что вижу проблему - если columnвывод не на терминал, вам нужно указать количество столбцов, или он будет выводить файлы один за другим; так column -c "$COLUMNS" ...должно работать в любом случае.
Муру
Вы запускаете (по крайней мере?) 5 процессов для каждого файла, так что, вероятно, это будет медленно, когда в каталоге много файлов…
JanC
10

Я думаю, что лучший способ отобразить тип файла с помощью этой команды:

file <filename>

Если вы хотите перечислить типы всех файлов в каталоге, просто используйте:

file *

Пример <code> file * </ code> с моего компьютера

Для получения более подробной информации об аргументах см .:

man file
singrium
источник
Хотя этот ответ не отвечает непосредственно на вопрос OP, он показывает правильный способ поиска файла MIME-типа файла и должен быть помечен как правильный ответ. Для того, чтобы получить mime typeтолько, использование: file --mime-type filename.
Педро Лобито
@PedroLobito Я думаю, что тесно связанный вопрос охватывает fileдовольно хорошо, но этот вопрос отличается.
десерт
Я голосую за этот ответ, учитывая, что вы были первым, кто дал fileответ. Поскольку я ответил остальным, этого недостаточно (его необходимо интегрировать с ls), поэтому я оставляю его на голосование. Спасибо.
user10853
1
файл * - лучший ответ
трамада
1
file --mime /dev/*для списка mimes в каталоге / dev вместо текущего
user1742529
7

Для ясности я собираюсь указать, что вы можете увидеть тип файла в основном смысле ls, используя -Fфлаг (классифицировать), который добавляет символ к имени файла в зависимости от его типа:

‘-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.

Вы можете видеть, что информация немного менее загадочно отображается в первой букве вывода ls -l. Ответ wjandrea описывает это более подробно.

Но я не думаю, что это то, что вы подразумеваете под типом файла. Команда lsне просматривает обычные файлы - только списки каталогов (в которых хранятся имена файлов) и inode (в которых хранятся метаданные, в том числе «тип» в смысле, упомянутом ранее).

Таким образом, lsкоманда не может показать тип файла в том смысле, является ли он изображением JPG или двоичным файлом, или текстовым файлом, или документом LibreOffice, потому что она не имеет этой информации.

Для этого, как указывает ответ Singrium , вам нужна fileкоманда, которая просматривает первые 50-100 КБ или около того содержимого файлов, чтобы определить их тип.

Занна
источник
@Zana Спасибо за внимание к этому флагу. Это сделало бы это сейчас, хотя это не то, что я искал (фактические типы файлов). За это я буду голосовать.
user10853
3

Одной из форм filetype является то, является ли файл обычным файлом, каталог, устройство, символическая ссылка и т. Д. lsМогут показать это с помощью параметров -lили -F.

  • Option -lпокажет тип файла в виде одного символа в начале списка, например:

    $ 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
    

    Где -находится обычный файл, dэто каталог и lсимволическая ссылка.

  • Опция -Fпокажет тип файла в виде суффикса, например:

    $ ls -F
    DIR/ FILE LINK@
    

    Где суффикс не является обычным файлом, /каталогом и @символической ссылкой.

Более подробная информация об этом доступна в info coreutils 'ls invocation'кратком изложении здесь:

Для -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

Для -F:

nothing for regular files
‘*’ regular files that are executable
‘/’ directories
‘@’ symbolic links
‘|’ FIFOs
‘=’ sockets
‘>’ doors
wjandrea
источник