O que poderia fazer com que o comando file no Linux reportasse um arquivo de texto como dados?

4

Eu tenho um par de arquivos fonte C ++ (um .cpp e um .h) que estão sendo reportados como tipo data pelo comando file no Linux. Quando executo o comando file -bi nesses arquivos, recebo essa saída (a mesma saída para cada arquivo):

application/octet-stream; charset=binary

Cada arquivo é claramente de texto simples (posso visualizá-los em vi ). O que está causando file relatar incorretamente o tipo desses arquivos? Poderia ser algum tipo de coisa Unicode? Esses dois arquivos foram criados no Windows (usando o Visual Studio 2005), mas estão sendo compilados no Linux (é um aplicativo de plataforma cruzada).

Qualquer ideia seria apreciada.

Atualizar : não vejo caracteres nulos em nenhum arquivo. Eu encontrei alguns caracteres estendidos no arquivo .cpp (em um bloco de comentário), removi-os, mas file ainda relata a mesma codificação. Eu tentei forçar a codificação no SlickEdit, mas isso não pareceu ter efeito. Quando abro o arquivo em vim , vejo uma linha [converted] assim que eu abro o arquivo. Talvez eu possa obter o vim para forçar a codificação?

    
por Jonah Bishop 11.04.2012 / 17:13

6 respostas

3

Encontrei o problema usando a pesquisa binária para localizar as linhas problemáticas.

head -n {1/2 line count} file.cpp > a.txt
tail -n {1/2 line count} file.cpp > b.txt

A execução de file em cada metade e a repetição do processo ajudaram a localizar a linha ofensiva. Eu encontrei um caractere Control + P ( ^P ) embutido nele. A remoção resolveu o problema. Escreverei um script em Perl para procurar esses caracteres (e outros estendidos) no futuro.

Um grande obrigado a todos que forneceram uma resposta para todas as dicas!

    
por 12.04.2012 / 01:18
4

Vim se esforça muito para entender o que quer que você jogue sem reclamar. Isso faz com que seja uma ferramenta relativamente ruim para diagnosticar a saída de file .

O aviso "[convertido"] do Vim indica que havia algo no arquivo que o vim não esperaria ver na codificação de texto sugerida pelas configurações locais (LANG, etc).

Outros já sugeriram

  • cat -v
  • xxd

Você pode tentar usar grepping para caracteres não-ASCII.

  • grep -P '[\x7f-\xff]' filename

A outra possibilidade são fins de linha não-padrão para a plataforma (ou seja, CRLF ou CR), mas eu esperaria file para lidar com isso e relatar "arquivo de texto do DOS" ou similar.

    
por 11.04.2012 / 18:24
3

Se você executar file -D filename , file exibirá informações de depuração, incluindo os testes que realiza. Perto do final, ele mostrará qual teste foi bem-sucedido na determinação do tipo de arquivo.

Para um arquivo de texto normal, é assim:

[31> 0 regex,=^package[ \t]+[0-9A-Za-z_:]+ *;,""]
1 == 0 = 0
ascmagic 1
filename.txt: ISO-8859 text, with CRLF line terminators

Isso lhe dirá o que descobriu para determinar que é o tipo mime.

    
por 11.04.2012 / 18:45
0

poderia ser que os arquivos foram salvos com um BOM no começo deles, embora eu achasse que uma versão recente do binário de arquivo também deveria reconhecer isso.

Você já tentou jogá-los por meio de algo como "head -2 | xxd" e ver se há um BOM presente?

* BOM = Byte Order Mark - às vezes presente em arquivos de texto unicode. link

    
por 11.04.2012 / 17:32
0

Provavelmente é um caractere não-ASCII do Unicode ou algum outro conjunto de caracteres. Como você está usando vi , que na maioria das distribuições Linux é alguma versão de vim , você pode procurar por esse caractere digitando

/[<Ctrl-V>x80-<Ctrl-V>xff]

e pressionando Enter, onde <Ctrl-V> significa digitar v enquanto pressiona a tecla Ctrl . Da mesma forma, você pode procurar por nulos (como Mehrdad sugeriu) com isto:

/<Ctrl-V>x00
    
por 11.04.2012 / 17:38
0

Qual charset / encoding / (codepage) são os arquivos em?
Talvez os arquivos tenham caráter (s) perdido (s). normalmente de codificação cruzada incorreta entre diferentes plataformas. Dados inválidos em seus arquivos podem estar causando file para relatar como você descreveu. Você pode testar a validade de um arquivo para uma codificação particular de charset testando-o com recode (ou iconv ).

Siga o link para obter uma lista de codificações de caracteres comuns

Este script lista as codificações do conjunto de caracteres (de $my_csets ) que não são válidas para o (s) seu (s) arquivo (s). Você pode listar todos os charsets via: recode -l

file="$1"    
my_csets="UTF-16 UTF-8 windows-1250 ASCII"

# Use the next lines to test all charsets
# =======================================
# all_csets=$(recode -l |sed -ne "/^[^:/]/p" | awk '{print $1}')
# my_csets=$all_csets

for cset in $my_csets ;do 
  <"$1" recode $cset.. &>/dev/null || echo  "$cset  ERROR: $?"
done 
    
por 11.04.2012 / 20:29