Як перелічити кількість рядків кожного файлу в каталозі у читаному для людини форматі.


41

У мене є список каталогів і підкаталогів, які містять великі файли csv. У цих файлах є близько 500 мільйонів рядків, кожен - це запис. Я хотів би знати

  1. Скільки рядків у кожному файлі.
  2. Скільки рядків у каталозі.
  3. Скільки рядків усього

Найголовніше, що мені це потрібно в "читаному для людини форматі", наприклад. 12,345,678, а не 12345678

Було б непогано навчитися робити це трьома способами. Звичайні інструменти для ванільної башти, awk тощо та перл (або пітон).

Відповіді:


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

BTW, 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, але це не вийшло.
Гексатонічний

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

Це не додає коми до числа, щоб зробити його більш зрозумілим для людини. Це просто додає нулі до кінця.
Гексатонічний

відлуння 1000000000000 | xargs printf "% 'd \ n" 1 000 000 000 000
Hexatonic

1
@Hexatonic printfне читає свої аргументи з stdin, а скоріше з командного рядка (порівняйте piping з echovs piping до 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 Для цього потрібно включити глобус. На macOS я вважаю, що його вимкнено поза коробкою. Я щойно надіслав редагування на вашу відповідь, в якому додається команда та як увімкнути globstar.
Тейлор Едмістон

2

Ця команда подасть список кодів рядків у кожному каталозі:

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

2

трохи запізнився в грі, але я отримав купу помилок аргументів із вищезазначеним через розмір dir. Це працювало для мене:

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 ідеальний, тому що він може читати список файлів із файлу замість аргументів (--files0 ).

Якщо ви на Mac і маєте домашню мову, вам слід зробити наступне:

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

Зауважте gwc замість wc .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.