считать строки в файле


65

Я уверен, что есть много способов сделать это: как я могу посчитать количество строк в текстовом файле?

$ <cmd> file.txt
1020 lines

Ответы:


99

Стандартный способ - with wc, который принимает аргументы для указания того, что он должен считать (байты, символы, слова и т. Д.); -lдля строк:

$ wc -l file.txt
1020 file.txt

Как мне посчитать строки в файле, если я хочу игнорировать комментарии? В частности, я хочу , чтобы не считать строки, начинающиеся с +, некоторое белое пространство (не могло быть пустого пространства) , а затем%, что является способом строки комментария появляется в мерзавце дифф файла MATLAB. Я попытался сделать это с помощью grep, но не смог понять правильное регулярное выражение.
Гдаля

@Gdalya Я надеюсь , что следующий конвейер будет делать это (тесты не были проведенными) cat matlab.git.diff | sed -e '/^\+[ ]*.*\%$/d' | wc -l. /regexp/dудаляет строку, если она совпадает regexp, и -eвключает соответствующий (IMNSHO) синтаксис для regexp.
дбанет

2
Почему не просто grep -v '^+ *%' matlab.git.diff | wc -l?
celtschk

@celtschk, если это обычно в строках комментария: возможно ли изменить вашу grepкоманду, чтобы рассматривать в качестве комментариев такие случаи " + Hello"(обратите внимание на пробел (ы) перед +)?
Сопалахо де Арриерес

1
@SopalajodeArrierez: Конечно, это возможно: grep -v '^ *+' matlab.git.diff | wc -l(Я предполагаю, что кавычки на самом деле не должны были быть частью строки; я также предполагаю, что обе строки с пробелами перед пробелами и без +них должны быть комментариями; если в как минимум один пробел является обязательным, либо заменить звезду *с \+, или просто добавить еще один пробел перед звездой). Возможно, вместо сопоставления только пробелов, вы захотите сопоставить произвольные пробелы; для этого замените пробел на [[:space:]]. Обратите внимание, что я также удалил соответствие, %поскольку это не в вашем примере.
celtschk

15

Как сказал Майкл, wc -lэто путь. Но, на всякий случай , если вы необъяснимо есть bash, perlили , awkно не wc, вот несколько решений:

Bash-только

$ LINECT=0; while read -r LINE; do (( LINECT++ )); done < file.txt; echo $LINECT

Perl Solutions

$ perl -lne 'END { print $. }' file.txt

и гораздо менее читаемый:

$ perl -lne '}{ print $.' file.txt

Awk Solution

$  awk 'END {print NR}' file.txt

15

Стивен Д забыл GNU sed:

sed -n '$=' file.txt

Кроме того, если вы хотите подсчет без вывода имени файла, и вы используете wc:

wc -l < file.txt

Просто ради этого:

cat -n file.txt | tail -n 1 | cut -f1

2
Или grep -c '', или tr -dc '\n' | wc -c, или nl -ba -nln | tail -n 1 |sed -e 's/[^0-9].*//'... Является ли что-нибудь из этого полезным само по себе (в отличие от того, на чем можно основываться, чтобы создать программу, которая делает больше, чем просто подсчет строк), кроме wc -lчистого (ba) sh?
Жиль "ТАК - перестань быть злым"

1
@ Жиль: Я думаю, что фраза «много способов» в вопросе вызвала вызов, к которому мы с Стивом поднялись.
Деннис Уильямсон

1
@ Жиль:sed 's/.*//' file.txt | uniq -c
Деннис Уильямсон

2
@ Жиль: О, ты имел в виду в первую очередь . uniq -c -w 0 file.txtи вы можете cut -c -7сохранить только номер. Или, более положительно uniq -c file.txt | awk '{c+=$1}END{print c}'. Как насчет dc(хотя это не POSIX)? uniq -c file.txt | cut -c -7 | sed '$alax' | dc -e '[pq]sb[+z1=blax]sa' -, bcявляется POSIX: uniq -c file.txt | cut -c -7 | sed -n ':a;${s/\n/ + /gp;b};N;ba' | bc. Самый простой ответ , если вы предполагаете , ограниченную длину строки: uniq -c -f 100000 file.txt.
Деннис Уильямсон

1
@JosipRodin: Цитаты добавлены
Деннис Уильямсон

11

Слово предупреждения при использовании

wc -l

потому что wc -l функционирует путем подсчета \ n, если последняя строка в вашем файле не заканчивается новой строкой, счетчик строк будет отключен на 1. (следовательно, старое соглашение оставляло символ новой строки в конце вашего файла)

Поскольку я никогда не могу быть уверен в том, что какой-либо из указанных файлов следует условию окончания последней строки новой строкой или нет, я рекомендую использовать любую из этих альтернативных команд, которая будет включать последнюю строку в число независимо от новой строки или нет.

sed -n $= filename
perl -lne 'END { print $. }' filename
awk 'END {print NR}' filename
grep -c '' filename

хорошее резюме. И добро пожаловать в Unix & Linux
Себастьян

Хм последний кусок действительно линия?
gena2x

1
Я уверен, что это зависит от использования каждого; «Последний фрагмент» - это обычно строка текста, которую кто-то не ограничил переводом строки. Сценарий использования, с которым я чаще всего сталкиваюсь, - это файл с одной строкой текста, который не заканчивается новой строкой. wc -l посчитал бы это как «0», тогда как в противном случае я бы рассчитывал на «1».
pretzels1337

3

В случае, если у вас есть только bash и абсолютно отсутствуют внешние инструменты, вы также можете сделать следующее:

count=0
while read
do
  ((count=$count+1))
done <file.txt
echo $count

Объяснение: цикл считывает стандартный ввод построчно ( readтак как мы все равно ничего не делаем с вводом чтения, переменная для его сохранения не предоставляется) и увеличивает переменную countкаждый раз. Из-за перенаправления ( <file.txtпосле done), стандартный вход для цикла от file.txt.


2

Вы всегда можете использовать команду grepследующим образом:

grep -c "^" file.txt

Он будет считать все фактические строки file.txt, независимо от того, содержит ли последняя строка символ LF в конце.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.