Как вы перечисляете количество строк каждого файла в каталоге в удобочитаемом формате.


41

У меня есть список каталогов и подкаталогов, которые содержат большие файлы CSV. В этих файлах около 500 миллионов строк, каждая из которых является записью. я бы хотел знать

  1. Сколько строк в каждом файле.
  2. Сколько строк в каталоге.
  3. Сколько всего строк

Самое главное, мне нужно это в «удобочитаемом формате», например. 12,345,678 вместо 12345678

Было бы неплохо узнать, как это сделать тремя способами. Обычные инструменты ванили, bash, awk и т. Д., И perl (или python).

Ответы:


57

Сколько строк в каждом файле.

Использование wc, первоначально для подсчета слов, я считаю, но это может сделать строки, слова, символы, байты и наибольшую длину строки. -lОпция говорит его подсчет строк.

wc -l <filename>

Это выведет количество строк в:

$ wc -l /dir/file.txt
32724 /dir/file.txt

Вы также можете передать данные в wc:

$ cat /dir/file.txt | wc -l
32724
$ curl google.com --silent | wc -l
63

Сколько строк в каталоге.

Пытаться:

find . -name '*.pl' | xargs wc -l

еще один вкладыш:

( find ./ -name '*.pl' -print0 | xargs -0 cat ) | wc -l

Кстати, wcкоманда считает коды новых строк, а не строк. Если последняя строка в файле не заканчивается кодом новой строки, это не учитывается.

Вы можете использовать grep -c ^, полный пример:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

Сколько всего строк

Не уверен, что я правильно понял ваш запрос. например, это выведет результаты в следующем формате, показывающем количество строк для каждого файла:

# wc -l `find /path/to/directory/ -type f`
 103 /dir/a.php
 378 /dir/b/c.xml
 132 /dir/d/e.xml
 613 total

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

# find /path/to/directory/ -type f -exec wc -l {} \; | awk '{total += $1} END{print total}'
 613

Самое главное, мне нужно это в «удобочитаемом формате», например. 12,345,678 вместо 12345678

Bash имеет встроенную функцию printf :

printf "%0.2f\n" $T

Как всегда, есть много разных методов, которые могут быть использованы для достижения тех же результатов, упомянутых здесь.


Кстати, как я могу использовать printf в ваших примерах? Я попытался передать по каналу из wc -l, но это не сработало.
Hexatonic

попробуйте> найти. -имя '* .pl' | xargs wc -l | awk '{printf ("% 0.2f", $ 1)} {print $ 2} "измените вывод printf для ваших нужд
malyy

Это не добавляет запятые к числу, чтобы сделать его более читабельным, хотя. Это просто добавляет нули в конец.
Hexatonic

эхо 1000000000000 | xargs printf "% 'd \ n" 1,000,000,000,000
Hexatonic

1
@Hexatonic printfне читает свои аргументы stdin, а скорее из командной строки (сравните трубопровод с echoпотоком с cat; catчитает из stdin, echoне читает ). Вместо этого используйте printf "$(find ... | xargs ...)"для предоставления вывода в качестве аргументов printf.
BallpointBen

13

Во многих случаях объединения wcкоманды и подстановочного знака *может быть достаточно.
Если все ваши файлы находятся в одном каталоге, вы можете позвонить:

wc -l src/*

Вы также можете перечислить несколько файлов и каталогов:

wc -l file.txt readme src/* include/*

Эта команда покажет список файлов и их количество строк.
Последняя строка будет суммой строк из всех файлов.


Чтобы подсчитать все файлы в каталоге рекурсивно:

Сначала включите globstar, добавив shopt -s globstarв свой .bash_profile. Для поддержки globstar требуется Bash ≥ 4.x, который может быть установлен brew install bashпри необходимости. Вы можете проверить свою версию с bash --version.

Затем запустите:

wc -l **/*

Обратите внимание, что этот вывод будет неправильным, если globstar не включен.


И для подсчета файлов в текущем каталоге рекурсивно:wc -l **/*
Тейлор Эдмистон

@TaylorEdmiston Для меня (на Mac), который считает файлы только на один каталог. Он пропускает файлы в текущем каталоге, и для любого экземпляра, который имеет глубину более одного каталога, он предупреждает, что это каталог: " wc: parent_dir/child_dir: read: Is a directory"
М. Джастин

@ Thomio Это требует, чтобы globstar был включен. На macOS я считаю, что он отключен из коробки. Я только что отправил правку на ваш ответ, в которой добавлена ​​команда и как включить globstar.
Тейлор Эдмистон

2

Эта команда выдаст список строк кода в каждом каталоге:

find . -name '*.*' -type f | xargs wc -l

2

Немного опоздал с игрой, но я получил кучу рассуждений об ошибках из-за размера директории. Это сработало для меня:

for i in $(find . -type f); do wc -l $i; done >> /home/counts.txt


0

catобъединит файлы в один и выведет все в stdout, вы можете сделать это wc -lдля общего количества строк файлов в каталоге:

cat /path/to/directory/* | wc -l

0

Я просто увеличу @malyy ответ для следующего (большой для комментария):

Сколько всего строк

Многие ответы используют wcопцию файла командной строки с xargs. Проблема в том, что xargs ограничен небольшим размером, зависящим от платформы.

Кроме того, есть разница между BSD (macOS) и GNU (linux / homebrew) wc.

GNU one идеален, потому что он может читать список файлов из файла вместо arguments ( --files0).

Если вы работаете на Mac и у вас есть homebrew, вы должны сделать следующее:

find . -name "*.pl" -print0 | gwc -l --files0=-

Обратите внимание на gwc вместо wc .

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