
Я использовал wc -l
для проверки количества строк, существующих в моих файлах. Это всегда работало нормально, но не в этот раз.
У меня есть 120 больших файлов, в каждом из которых должно быть не менее двух строк. Я только что выполнил некоторую работу по редактированию текста в этих файлах, чтобы удалить и добавить новые строки. Я пытался проверить окончательное количество строк, используя wc -l *
как обычно. Вывод показал, что большинство файлов имели только одну строку.
Я открыл один из файлов (который показал из результата команды, что в нем была только одна строка) с помощью vim
и я вижу, что в нем было ровно 2 строки. Выйдите vim
и проверьте снова с помощью wc -l
, номер строки для этого файла затем появился как 2.
Кто-нибудь знает, что здесь произошло? И как мне решить эту проблему, вместо того, чтобы открывать все 120 файлов с помощью vim
?
PS: Последняя строка моих файлов не была пустой.
решение1
Распространенная реализация GNU wc
говорит:
«wc» подсчитывает количество байтов, символов, слов, разделенных пробелами,
и символов новой строки в каждом указанном ФАЙЛЕ или стандартном вводе, если ничего не указано или для ФАЙЛА «-».
поэтому если в файле нет завершающего символа новой строки, часть "строки" вывода wc
будет на единицу меньше ожидаемого. Например, следующий код выведет 1
printf 'hello\nworld' | wc -l
OP подтвердил в комментариях, что vim сообщает об отсутствии последней новой строки. Простое исправление, если известно, что во всех файлах есть эта проблема, это
for f in *
do
echo >> "$f"
done
для добавления новой строки к каждому файлу.
Условный способ добавления новой строки в конец всех файлов, если она отсутствует, — использовать sed.
sed -s -i '$s/$/\n/;P;d' *
использует некоторые расширения gnu, -s
чтобы обрабатывать каждый файл отдельно, -i
чтобы делать редактирование на месте и разрешать \n
представлять новую строку. Сама программа sed говорит в последней строке каждого файла добавить новую строку, и для каждой строки вывести до первой новой строки и перейти на следующую строку.
решение2
Это не совсем ответ, но я поделюсь небольшим персональным инструментом, который я часто использую для нормализации текстовых файлов (txtnorm):
#!/usr/bin/perl -spi
our($s);
s/\n\r|\r\n|\n|\r/\n/g; ## normalize \n
s/^(\xFF\xFE|\xFE\xFF|\xEF\xBB\xBF)//; ## remove BOM !
s/(?<=.)\z/\n/; ## ensure newline at eof
if($s){ s/\xC2\xA0/ /g } ## -s non breaking spaces-> " "
txtnorm *.txt
нормализует конец строк, обеспечивает перевод строки в конце файла, удаляет BOM и (с -s) может нормализовать неразрывные пробелы.
Обязательно используйте его ТОЛЬКО для текстовых файлов.