Вывод файла из программы C, которая ведет себя странно при подсчете строк

Я использую C для анализа большого плоского файла и вывода соответствующих строк в выходной файл. Выходной файл должен содержать около 70 000 строк.

Если я открою файл в gedit, он отобразится точно так, как ожидалось, с правильным количеством строк и длиной строк.

Однако запуск wc -l <file> возвращает 13 156. Как и grep -c "" <file>.

tail <file> возвращает последние 10 строк, которые я вижу в gedit. head <file> возвращает первые 10 строк. Но tail -n +8000 | head -n 1, который должен вернуть 8000-ю строку, возвращает текст, который я вижу в строке 34804 в gedit.

Я ожидал бы таких результатов, если бы в файле отсутствовали символы новой строки. Но у gedit, похоже, нет проблем с этим. Кроме того, wc -L <file>, отображающий максимальную длину строки, возвращает 142 байта, как и ожидалось. Размер файла чуть больше 9 000 000 байт, как и ожидалось.

Если wc -L <file> = 142, а wc -c <file> = 9046609, то как может wc -l <file> = 13156?

Кто-нибудь знает, что я сделал неправильно при записи в этот файл?


person Fred Olsen    schedule 23.07.2011    source источник
comment
Может быть, вы используете '\n' 13156 раз, а '\r' другое?   -  person user786653    schedule 23.07.2011
comment
Возможно, gedit переносит строки и считает строки после переноса?   -  person R.. GitHub STOP HELPING ICE    schedule 23.07.2011


Ответы (1)


Вероятно, это какая-то странная комбинация символов возврата ('\r') и перевода строки ('\n').

Предполагая, что у вас есть версия GNU Coreutils «tr», вы можете использовать эти команды для подсчета количества каждого символа в файле:

tr -d -c '\n' FILE | wc -c

tr -d -c '\r' FILE | wc -c

Для обычного текстового файла в стиле Unix вторая команда должна напечатать 0. Для текстового файла в стиле Windows обе должны напечатать одно и то же число.

Команда «файл» также, вероятно, подскажет вам что-то полезное.

person Keith Thompson    schedule 23.07.2011
comment
Да, проблема оказалась с символами LF и CR. Строки исходных файлов заканчивались на CR LF. Однако я допустил ошибку с моими вызовами read() и обрезал определенные строки после CR. Поэтому не все новые строки считывались в выводе. Gedit был достаточно умен, чтобы отобразить его правильно, и, по-видимому, опция максимальной длины строки в wc останавливается после CR. Но в файле было всего 13 156 LF. - person Fred Olsen; 24.07.2011
comment
@Keith: FWIW, некоторые файлы Mac имеют «\ r» в качестве разделителей строк. - person Rudy Velthuis; 24.07.2011
comment
@Rudy: Да, ты прав. Насколько я помню, MacOS до MacOS X использовала '\r'; MacOS X основана на Unix, поэтому использует '\n'. Возможен ряд других форматов текстовых файлов, включая записи с фиксированной шириной, но вы вряд ли столкнетесь с чем-то подобным, если не используете старый мейнфрейм. - person Keith Thompson; 24.07.2011
comment
@Keith: разнообразие записей фиксированного размера действительно звучит антикварно. Я никогда не видел его за 30 лет. - person Rudy Velthuis; 24.07.2011