У меня есть файл с пустыми строками в конце файла. Можно ли использовать grep
для подсчета количества пустых строк в конце файла с именем файла, передаваемым в сценарии как переменная?
text-processing
grep
wc
Рагхунат Чоудхари
источник
источник
grep
@MichaelJohn за чистоту в моей книге.Ответы:
Если пустые строки только в конце
или же:
источник
grep -cv . myFile
это еще один способ написать это (для игроков в гольф код). Но я нашел решение,grep
если в файле есть пустые строки.grep -cv .
также будет считать строки, содержащие только байты, которые не образуют допустимых символов.Просто для удовольствия, некоторые привидение
sed
:Объяснение:
/./
адреса строк с любым символом, поэтому/./!
адреса непустые строки; для нихH
команда добавляет их в область ожидания. Таким образом, если для каждой пустой строки мы добавили одну строку в пространство удержания, всегда будет на одну строку больше, чем количество пустых строк. Мы позаботимся об этом позже.//h
пустой шаблон соответствует последнему регулярному выражению, которое было любым символом, поэтому любая непустая строка адресуется и перемещается в пространство удержанияh
командой, чтобы «сбросить» собранные строки до 1. Когда следующая пустая строка будет добавлена, снова будет два, как и ожидалось.$!d
останавливает сценарий без вывода для каждой строки, кроме последней, поэтому дальнейшие команды выполняются только после последней строки. Таким образом, все пустые строки, которые мы собрали в области хранения, находятся в конце файла. Хорошо.//d
: Командаd
снова выполняется только для непустых строк. Так что, если последняя строка не была пустой,sed
выйдет без вывода. Ноль линий. Хорошо.x
обмены содержат пространство и пространство шаблона, поэтому собранные строки теперь находятся в пространстве шаблона для обработки.s/\n//
.wc -l
.источник
Еще несколько GNU
tac
/tail -r
опций:Или:
Обратите внимание, что на выходе:
То есть, если после последней полной строки есть дополнительный пробел (который некоторые могут рассматривать как лишнюю пустую строку, но по определению текста POSIX это недопустимый текст), они дадут 0.
POSIXly:
но это означает, что файл будет прочитан полностью (
tail -r
/tac
будет считывать файл в обратном направлении с конца для поиска файлов). Это дает1
на выходеprintf 'x\n '
.источник
Поскольку вы на самом деле запрашиваете
grep
решение, я добавляю это, полагаясь только на GNUgrep
(хорошо, также используя синтаксис оболочки иecho
...):Что я здесь делаю?
$(grep -c ".*" "$1")
считает все строки в файле, затем вычитает файл без конечных пустых строк.И как их получить?
$(grep -B42 . "$1"
будет обрабатывать все непустые строки и 42 строки перед ними, поэтому он будет печатать все до последней непустой строки, если перед непустой строкой находится не более 42 последовательных пустых строк. Чтобы избежать этого ограничения, я принимаю$(grep -cv . "$1")
в качестве параметра для-B
опции, которая является общим количеством пустых строк, поэтому всегда достаточно большой. Таким образом, я убрал конечные пустые строки и могу использовать их|grep -c ".*"
для подсчета строк.Блестящий, не правда ли? (-;
источник
tac | grep
первый непустой с-m -A 42
, затем минус один. Я не уверен, что является более эффективным, но вы также могли быwc -l | cut -d' ' -f1
вместо того, чтобы вырезать пустые строки?tac
,wc
иcut
, но здесь я пытался ограничитьсяgrep
. Вы можете назвать это извращением, я называю это спортом. (-;Другое
awk
решение. Этот вариант сбрасывает счетчикk
каждый раз, когда появляется непустая строка. Затем каждая строка увеличивает счетчик. (Итак, после первой непустой строки длиныk==0
.) В конце мы выводим количество пересчитанных нами строк.Подготовьте файл данных
Подсчитайте конечные пустые строки в образце
В этом определении пустая строка может содержать пробелы или другие пустые символы; это все еще пусто Если вы действительно хотите считать пустые строки, а не пустые, измените
NF
на$0 != ""
.источник
$0 > ""
? Использует то,strcoll()
что было бы менее эффективно, чем то,$0 != ""
которое используетсяmemcmp()
во многих реализациях (POSIX раньше требовал его использования,strcoll()
хотя).$0 > ""
может отличаться$0 != ""
. Вawk
любом случае я склонен относиться к «медленным» операторам (например, если я знаю, что у меня большой ввод данных в качестве входных данных, а обработка критична по времени, я посмотрю, что можно сделать, чтобы уменьшить объемawk
обработки - я использовалиgrep | awk
конструкции в таких ситуациях). Тем не менее, имея быстрый взгляд на то , что я предполагаю , что это определение POSIX я не вижу каких - либо ссылок на любойstrcoll()
илиmemcmp()
. Что мне не хватает?strcoll()
== строки должны сравниваться с использованием последовательности сопоставления для конкретной локали . Сравните с предыдущим изданием . Я был тем, кто поднял это. См. Также austingroupbugs.net/view.php?id=963a <= b && a >= b
не обязательно совпадает сa == b
. Ой!awk
илиbash
(для его[[ a < b ]]
операторов) в en_US.UTF-8 локалей в системах GNU, например , для①
против②
, например (дляbash
, ни один из<
,>
,=
возвращает истину для тех , кто). Возможно, это ошибка в определении этих локалей больше, чем в bash / awkТвердый
awk
+tac
раствор:Образец
input.txt
:Действие:
!NF
- гарантирует, что текущая строка пуста (не имеет полей)NR==++c
- обеспечение последовательного порядка пустых строк. (NR
- номер записи,++c
- равномерно увеличенный вспомогательный счетчик)cnt++
- счетчик пустых строкВыход:
источник
IIUC, следующий скрипт вызвал
count-blank-at-the-end.sh
бы работу:Пример использования:
Я тестировал его в
GNU bash
,Android mksh
иksh
.источник
Альтернативное
Python
решение:Пример input.txt:
Действие:
Выход:
https://docs.python.org/3/library/itertools.html?highlight=itertools#itertools.takewhile
источник