Что может заставить файловую команду в Linux сообщать о текстовом файле в виде данных?

У меня есть несколько исходных файлов C++ (один.cpp и один.h), которые сообщаются как данные типа file Команда в Linux. Когда я бегу file -bi Команда против этих файлов, мне дают этот вывод (тот же вывод для каждого файла):

application/octet-stream; charset=binary

Каждый файл явно текстовый (я могу просмотреть их в vi). Что вызывает file искажать тип этих файлов? Может ли это быть что-то вроде Unicode? Оба эти файла были созданы в Windows-land (с использованием Visual Studio 2005), но они компилируются в Linux (это кроссплатформенное приложение).

Любые идеи были бы хорошы.

Обновление: я не вижу нулевых символов ни в одном файле. Я нашел несколько расширенных символов в файле.cpp (в блоке комментариев), удалил их, но file все еще сообщает ту же кодировку. Я пытался форсировать кодировку в SlickEdit, но, похоже, это не дало эффекта. Когда я открываю файл в vim, Я вижу [converted] линия, как только я открою файл. Возможно, я смогу получить vim для принудительного кодирования?

7 ответов

Решение

Я нашел проблему, используя бинарный поиск, чтобы найти проблемные строки.

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

Бег file против каждой половины, и повторяя процесс, помог мне найти оскорбительную строку. Я нашел Control + P (^P) характер встроен в него. Удаление это решило проблему. Я напишу сценарий Perl для поиска этих символов (и других расширенных) в будущем.

Большое спасибо всем, кто дал ответ на все советы!

Вим изо всех сил старается понять, что ты им бросаешь, не жалуясь. Это делает его относительно плохим инструментом для диагностики fileвыходной.

Уведомление Vim "[преобразованный]" указывает на то, что в файле есть что-то, что vim не ожидает увидеть в кодировке текста, предложенной вашими настройками локали (LANG и т. Д.).

Другие уже предложили

  • cat -v
  • xxd

Вы можете попробовать поискать символы, не входящие в ASCII.

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

Другая возможность - нестандартные окончания строки для платформы (например, CRLF или CR), но я ожидаю file чтобы справиться с этим и сообщить "текстовый файл DOS" или подобное.

Если вы бежите file -D filename, file отображает отладочную информацию, включая тесты, которые она выполняет. Ближе к концу, он покажет, какой тест прошел успешно при определении типа файла.

Для обычного текстового файла это выглядит так:

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

Это скажет вам, что он нашел, чтобы определить, что это тот тип пантомимы.

Я работал с довольно большими файлами, поэтому такие решения, какcat -v, который просто печатает все, включая непечатаемые символы, не был вариантом.

Чтобы найти только строки, содержащие непечатаемые символы, я использовал:

      grep -n '[^[:print:]]' Exploit.in_noctrls.txt

В какой кодировке / кодировке /(кодовой странице) находятся файлы?
Возможно, файлы имеют случайные символы. как правило, из-за плохой перекодировки между разными платформами. Неправильные данные в ваших файлах могут быть причиной file сообщить, как вы описали. Вы можете проверить правильность файла для определенной кодировки кодировки, протестировав его с помощью recode (или же iconv).

Перейдите по ссылке для получения списка кодировок общих символов

Этот скрипт перечисляет кодировки кодировки (из $my_csets), которые не действительны для вашего файла (ов). Вы можете перечислить все кодировки через: 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 

Вполне возможно, что файлы были сохранены с BOM в начале их, хотя я бы подумал, что недавняя версия двоичного файла должна это признать.

Вы пробовали сбросить их через что-то вроде "head -2 | xxd" и посмотреть, есть ли спецификация?

* BOM = Byte Order Mark - иногда присутствует в текстовых файлах Unicode. http://en.wikipedia.org/wiki/Byte_order_mark

Вероятно, это не-ASCII символ из Unicode или другого набора символов. Так как вы используете vi, которая в большинстве дистрибутивов Linux является некоторой версией vimвы можете найти этого персонажа, набрав

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

и нажмите Enter, где <Ctrl-V> значит печатать v нажимая Ctrl ключ. Точно так же вы можете искать пустые значения (как предложил Mehrdad) с помощью этого:

/<Ctrl-V>x00
Другие вопросы по тегам