Что может заставить файловую команду в 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