Что считает wc
wc (word count) — простая утилита для подсчёта строк, слов, байтов или символов в файле или stdin. Один из старейших UNIX-инструментов (UNIX V1, 1971).
Базовый запуск без флагов:
$ wc /etc/passwd
42 120 2389 /etc/passwd
Три числа: lines, words, bytes. Для DE интереснее по одному:
Каждый флаг отвечает за одну метрику.
Самый частый: wc -l
$ wc -l data.csv
1247 data.csv
$ wc -l < data.csv
1247
# < (input redirection) убирает имя файла из вывода — удобно для скриптов
$ ls /var/log/ | wc -l
38
# Сколько файлов в /var/log/
Gotcha: trailing newline
$ printf "hello" | wc -l # без \n в конце
0
$ printf "hello\n" | wc -l # с \n в конце
1
wc считает newline-символы, не «строки в человеческом понимании». Файл без trailing \n даст один «недосчитанный» лайн. На POSIX-системах это часть стандарта: каждая строка ДОЛЖНА заканчиваться на \n. Большинство утилит ведёт себя именно так.
Это аккуратно: если у тебя файл с N строками и wc -l показывает N-1 — проверь, есть ли \n в конце:
$ tail -c 1 file.csv | xxd
00000000: 0a .
# Если последний байт 0x0a — это \n, всё хорошо
# Если что-то другое — последняя строка без newline
CSV: сколько rows
$ wc -l data.csv
1248 data.csv
# 1248 строк всего, но одна — заголовок
# rows = 1248 - 1 = 1247
# Без header:
$ tail -n +2 data.csv | wc -l
1247
tail -n +2 начинает с 2-й строки (skip header). Это идиома wc -l rows для CSV с header.
DE-кейсы
1. Размер набора данных
$ wc -l /data/orders/*.csv
1247 orders_2026_05_10.csv
1389 orders_2026_05_11.csv
1450 orders_2026_05_12.csv
4086 total
С несколькими файлами wc добавляет строку total — полезно для quick sanity check.
2. Самые «толстые» файлы по строкам
$ find . -name '*.py' -exec wc -l {} + | sort -n | tail -10
234 dags/load_dim_users.py
289 dags/process_events.py
312 dags/sync_orders.py
...
1247 utils/legacy_helpers.py
find ... -exec wc -l {} + — батчинг (плюс), пакет файлов одним вызовом wc. Гораздо быстрее -exec ... \;. Сортировка по строкам подсвечивает самые большие файлы — кандидаты на refactor.
3. Подсчёт уникальных значений
$ cut -d ',' -f 4 orders.csv | sort -u | wc -l
12
# 12 уникальных стран в orders
4. Топ N с подсчётом
# Все ERROR в логе за сегодня (сегодняшняя дата в начале строки)
$ grep -c "^$(date +%Y-%m-%d).*ERROR" app.log
73
grep -c быстрее grep ... | wc -l: grep не строит вывод и не открывает второй pipe.
5. Размер файла в байтах
$ wc -c data.csv
123456 data.csv
# Или через stat для большей точности:
$ stat -c '%s' data.csv
123456
Для размера лучше stat или ls -l: они читают метаданные inode, не file content. wc -c должен прочитать весь файл (на современном wc оптимизация — sized files через lseek к концу, но на streams не работает).
Bytes vs Chars: критично для UTF-8
$ echo -n "Привет" > greeting.txt
$ wc -c greeting.txt
12 greeting.txt # 12 байт
$ wc -m greeting.txt
6 greeting.txt # 6 символов
$ echo -n "hello" > hello.txt
$ wc -c hello.txt
5 hello.txt # 5 байт
$ wc -m hello.txt
5 hello.txt # 5 символов (ASCII = bytes == chars)
UTF-8 кириллица — 2 байта на букву. Эмодзи — 4 байта (некоторые до 8 в surrogate pairs). Для длинных файлов это важная разница.
В DE-задачах это критично:
- Limits в БД часто в байтах (VARCHAR(255) в MySQL latin1 = 255 байт, в utf8mb4 — 255 символов = до 1020 байт)
- Limits API — иногда в символах (Twitter character limit), иногда в байтах
- HTTP
Content-Length— всегда байты
wc через stdin
wc принимает stdin когда нет файлов в аргументах:
$ ls /var/log | grep '.log$' | wc -l
12
$ ps -ef | grep python | wc -l
4
Это classic Linux idiom: «как много чего-то». wc -l — это «COUNT(*) в bash».
Когда wc недостаточно
wc примитивен. Для сложного counting:
- uniq -c — count по группам
- awk — programmable count с условиями
- grep -c — count строк со совпадением (быстрее wc -l после grep)
Например:
# Сколько уникальных users заходило в системе?
$ awk -F: '{print $1}' /etc/passwd | wc -l # все users
$ awk -F: '$3 >= 1000 {print $1}' /etc/passwd | wc -l # только regular
awk здесь добавляет фильтр (UID >= 1000), который wc сам сделать не может.
Попробуй сам
- Считай строки в /etc/passwd:
wc -l /etc/passwd - Сколько Python-файлов в проекте:
find . -name '*.py' 2>/dev/null | wc -l - Размер самого длинного слова в /usr/share/dict/words (если есть):
wc -L /usr/share/dict/words 2>/dev/null - Сравни bytes и chars для UTF-8:
echo -n "日本語" | wc -c # 9 байт echo -n "日本語" | wc -m # 3 символа - Топ-5 самых больших файлов в /etc:
wc -l /etc/* 2>/dev/null | sort -n | tail -6 | head -5
macOS-различия
- wc на macOS идентичен GNU wc для базовых флагов.
-L(longest line length) поддерживается на BSD wc.- Поведение
wc -mзависит отLANG/LC_ALL: если выставлен UTF-8, считаются символы; если C/POSIX — считаются байты (то же, что -c).
Главное
wc -l— строки (newline count, требует trailing \n).wc -w— слова (whitespace-separated).wc -c— БАЙТЫ, не символы.wc -m— символы (UTF-8 aware с правильным locale).wc -L— длина самой длинной строки.- Для размера лучше
statилиls -l(читает metadata, не content). - Без trailing \n в файле последняя «строка» не засчитается в
-l. - Для CSV с header:
tail -n +2 file.csv | wc -lили($(wc -l < file.csv) - 1). grep -c PATTERN fileбыстрееgrep PATTERN file | wc -l.