Como exibo o tipo de arquivo com ls?

12

Não sei se lsé capaz de exibir uma coluna de tipo de arquivo.

Fazer uma pesquisa on-line rápida e pesquisar no mannão revelou essa capacidade. É capaz de fazer isso?

Esclarecimento: Isso é especialmente útil se os arquivos não tiverem uma extensão.

Atualizar

A partir de 28/04/2018, as respostas foram bastante interessantes, mas não forneceram o que eu estava procurando. Mais especificamente,

  • filefornece os tipos de arquivos reais, mas não se integra bem a eles ls. Especificamente, eu usols -lhtrpG --group-directories-first --color=always

  • ls -Fé uma lssolução, no entanto, fornece símbolos e não uma coluna de tipos de arquivos reais.

Por esse motivo, não marquei nenhuma das respostas como a que estou procurando.

user10853
fonte
informações relacionadas: legível por humanos: ls -lahtrpF --group-directories-first --color=always /devou ls -lsahG /devlegível por programa ls -lsa /dev. consulte a man lsdocumentação para obter detalhes.
user1742529 7/03

Respostas:

16

fileé definitivamente a escolha certa para obter as informações de tipo de arquivo que você deseja. Para combinar sua saída com a de lssugiro usar find:

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

Ele localiza todos os arquivos no diretório atual e imprime a saída ls -dilse a saída file -bdele, cada uma em uma linha própria. Exemplo de saída:

  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

Mas, como você não deseja uma linha de tipo de arquivo , mas sim uma coluna , aqui está uma maneira de se livrar do caractere de nova linha entre as linhas:

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

Saída de amostra:

-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

Essa nova coluna é bastante longa, então vamos cortar tudo desde a primeira vírgula:

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

A saída disso é assim:

-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

Isso não é muito útil, então que tal um alias? Com a seguinte linha no seu ~/.bash_aliasesarquivo, você só precisa executar lsfpara obter a saída acima para o diretório atual.

alias lsf='find -maxdepth 1 -type f -exec sh -c "ls -l {} | tr '"'\n'"' '"'\t'"'; file -b {} | cut -d, -f1" \;'
sobremesa
fonte
1
Se você usar uma função em vez de um alias, isso será um inferno para citações e, se você usar pasteou column, poderá obter um melhor alinhamento: lsf () { find -maxdepth 1 -type f -exec bash -c 'column <(ls -l "$@") <(file -b "$@" | cut -d, -f1)' _ {} + ; }o problema de alinhamento não é evidente na resposta devido aos tamanhos e datas semelhantes. (Este também será um pouco mais rápido, uma vez que os comandos será invocado menos vezes em vez de uma vez por arquivo.)
Muru
@ muru Obrigado pelas muitas boas sugestões! Essa columnabordagem funciona para você? Ele só imprime a saída ls -lpara cada arquivo seguido por file's saída para cada arquivo para mim, como se o shell só iria fazer ls -l "$@"; file -b "$@" | cut -d, -f1...
sobremesa
Faz. paste.ubuntu.com/p/KjPthXPDPb - a parte superior é do alias e a parte inferior é a função, ambas executadas a partir /etc.
Muru
Acho que vejo o problema - se columna saída não estiver no terminal, é necessário especificar a contagem de colunas ou os arquivos serão gerados um após o outro; portanto, column -c "$COLUMNS" ...deve funcionar nos dois casos.
Muru
Você está iniciando (pelo menos?) 5 processos para cada arquivo, portanto isso provavelmente será lento quando houver muitos arquivos em um diretório ...
JanC
10

Eu acho que a melhor maneira de exibir um tipo de arquivo é usando este comando:

file <filename>

Se você deseja listar os tipos de todos os arquivos em um diretório, use:

file *

Amostra <code> file * </code> do meu computador

Para mais detalhes sobre os argumentos, consulte:

man file
singrium
fonte
Embora essa resposta não responda diretamente à pergunta do OP, ela mostra a maneira correta de encontrar o tipo MIME de um arquivo e deve ser marcada como a resposta correta. Para obter a mime typeúnica, use: file --mime-type filename.
Pedro Lobito
@PedroLobito Acho que a pergunta intimamente relacionada cobre filemuito bem, mas essa pergunta é diferente.
dessert
Voto esta resposta, já que você foi o primeiro a fileresponder. Como eu respondi aos outros, isso não é suficiente (precisa ser integrado ao ls), por isso mantenho-o em votação. Obrigado.
usar o seguinte comando
1
file * é a melhor resposta
tramada 13/01
1
file --mime /dev/*para list mimes no diretório / dev em vez de atual
user1742529 07/03
7

Para maior clareza, vou apontar que você pode ver o tipo de arquivo em um sentido básico com ls, usando a -Fflag (classify) que anexa um símbolo ao nome do arquivo, dependendo do seu tipo:

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

Você pode ver essas informações um pouco menos criptografadas na primeira letra da saída de ls -l, no entanto. A resposta de wjandrea descreve isso com mais detalhes.

Mas acho que não é isso que você entende por tipo de arquivo. O lscomando não procura dentro dos arquivos regulares - apenas nas listagens de diretório (que armazenam nomes de arquivos) e inodes (que armazenam metadados, incluindo o "tipo" no sentido mencionado anteriormente).

Portanto, o lscomando não pode mostrar o tipo de arquivo no sentido de ser uma imagem JPG ou um arquivo binário ou um arquivo de texto ou um documento do LibreOffice de algum tipo, porque não possui essas informações.

Para isso, como a resposta do singrium indica, você precisa do filecomando, que analisa os primeiros 50-100kB ou mais do conteúdo dos arquivos para determinar seu tipo.

Zanna
fonte
@Zana Obrigado por chamar minha atenção para esta bandeira. Isso faria isso por enquanto, embora não seja o que eu estava procurando (tipos de arquivos reais). Por isso vou votar.
usar o seguinte comando
3

Uma forma de tipo de arquivo é se um arquivo é um arquivo regular, diretório, dispositivo, link simbólico etc. lspode mostrar isso usando as opções -lou -F.

  • A opção -lmostrará o tipo de arquivo como um único caractere no início de uma listagem, por exemplo:

    $ 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
    

    Onde -está um arquivo regular, dé um diretório e lé um link simbólico.

  • A opção -Fmostrará o tipo de arquivo como um sufixo, por exemplo:

    $ ls -F
    DIR/ FILE LINK@
    

    Onde nenhum sufixo é um arquivo regular, /é um diretório e @é um link simbólico.

Mais informações sobre isso estão disponíveis em info coreutils 'ls invocation', resumidas aqui:

Para -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

Para -F:

nothing for regular files
‘*’ regular files that are executable
‘/’ directories
‘@’ symbolic links
‘|’ FIFOs
‘=’ sockets
‘>’ doors
wjandrea
fonte