Bash и Unix-утилиты для Data Engineer
Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.
Содержание:
Зачем DE Bash
Bash — повседневный инструмент DE: ad-hoc анализ логов, обработка CSV до загрузки в DWH, отладка пайплайнов на серверах, написание простых ETL-скриптов. На собесе обязательно дадут задачу: «есть лог из миллионов строк, найди топ-10 IP по числу запросов» — ожидают цепочку из 4-5 утилит за 30 секунд.
Главная боль без Bash — DE пишет 50 строк Python там, где нужно grep | awk | sort | uniq -c | sort -rn | head. На проде такие скрипты живут вечно и тратят время команды.
Pipes и редиректы
cmd1 | cmd2 # stdout cmd1 → stdin cmd2
cmd > file # stdout → файл (перезапись)
cmd >> file # stdout → файл (добавление)
cmd 2> err.log # stderr → файл
cmd > out 2>&1 # stdout + stderr в один файл
cmd > /dev/null # выкинуть stdout
cmd | tee file # stdout в файл И в следующий pipeТонкость: cmd1 | cmd2 запускает обе команды параллельно (cmd2 не ждёт окончания cmd1). На больших данных это даёт streaming.
grep, awk, sed
grep — поиск по regex.
grep "ERROR" app.log # строки с ERROR
grep -i "error" app.log # case-insensitive
grep -v "DEBUG" app.log # инверсия
grep -E "(ERROR|WARN)" app.log # extended regex
grep -c "ERROR" app.log # count
grep -A 3 "ERROR" app.log # +3 строки после
grep -B 3 "ERROR" app.log # +3 строки до
grep -r "TODO" src/ # рекурсивно по директорииawk — работа с колоночными данными. Дефолтный разделитель — пробел/таб.
awk '{print $1}' file # первая колонка
awk -F',' '{print $2}' file.csv # разделитель = запятая
awk '$3 > 100 {print $0}' file # фильтр + вывод всей строки
awk '{sum += $2} END {print sum}' # сумма второй колонки
awk -F',' 'NR>1 {a[$1]++} END {for (k in a) print k, a[k]}' file.csv # уникальные счётчикиsed — потоковое редактирование.
sed 's/old/new/g' file # замена (g = global, all occurrences)
sed -n '5,10p' file # строки 5-10
sed -i 's/foo/bar/g' file # in-place (Linux)
sed -i '' 's/foo/bar/g' file # in-place (macOS)cut, sort, uniq
cut — извлечь колонки.
cut -d',' -f1,3 file.csv # 1-я и 3-я колонка csv
cut -c1-10 file # символы 1-10 каждой строкиsort — сортировка.
sort file # по возрастанию
sort -r file # обратно
sort -n file # числовая
sort -k 2 -n file # по 2-й колонке, числовая
sort -t',' -k 3 -nr file.csv # csv, 3-я колонка, число, обратно
sort -u file # уникальные (sort + dedup)uniq — удаление дубликатов подряд идущих строк (требует sorted вход).
sort file | uniq # уникальные
sort file | uniq -c # с count
sort file | uniq -c | sort -rn # топ по частотеКлассическая комбинация — топ N в логе:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10jq для JSON
Bash сам по себе плохо работает с JSON. Стандартный инструмент — jq.
jq '.user.name' file.json # достать поле
jq '.[]' file.json # элементы массива
jq '.users[] | {id, name}' file.json # выбор полей
jq -r '.name' file.json # raw output (без кавычек)
jq 'select(.age > 30)' users.json
jq '.[] | "\(.id),\(.name)"' file.json # CSV-формат
cat events.ndjson | jq -c 'select(.event == "click")'-c — compact (one line per JSON), удобно для NDJSON.
cron и процессы
cron-синтаксис:
* * * * * команда
│ │ │ │ │
│ │ │ │ └── день недели (0-7, 0 и 7 = вс)
│ │ │ └──── месяц (1-12)
│ │ └────── день месяца (1-31)
│ └──────── час (0-23)
└────────── минута (0-59)0 2 * * * # каждый день в 02:00
*/15 * * * * # каждые 15 минут
0 0 * * 0 # каждое воскресенье в 00:00
0 9 1 * * # 1-го числа каждого месяца в 09:00Процессы:
ps aux | grep python # найти процесс
kill -9 12345 # форс-убить процесс
nohup script.sh > log.txt 2>&1 & # запустить в фоне, не убивать при logout
jobs # фоновые задачи
disown -h # отвязать от терминала
htop # интерактивный мониторингСигналы: SIGTERM (15) — мягкое завершение, SIGKILL (9) — принудительное, SIGHUP (1) — перезагрузка конфига.
Частые ошибки
Парсинг CSV через awk -F','. На CSV с экранированными кавычками и запятыми внутри — сломается. Использовать csvkit/miller или Python.
Сортировать огромные файлы в RAM. sort использует disk-spill, но LC_ALL=C sort (без локали) ускоряет на порядок.
cat file | grep pattern. «Useless use of cat». Просто grep pattern file.
ls | grep pattern. Не парсить вывод ls. Использовать globbing (*.csv) или find.
Игнорировать set -euo pipefail в скриптах. Без него ошибка где-то в пайпе — скрипт продолжается с битыми данными.
Замена in-place без backup. sed -i без -i.bak — опасно. Сначала проверить на dry-run, потом backup, потом replace.
Игнорировать exit codes. cmd1 && cmd2 — следующая команда выполнится только при успехе предыдущей. || — наоборот. Без проверки exit codes цепочки молча проваливаются.
Связанные темы
- Подготовка к собесу Data Engineer
- Idempotency пайплайна для DE
- Как построить ETL pipeline для аналитика
- Airflow на собесе DE
- SQL для Data Engineer: собеседование
FAQ
Bash или Python для скриптов DE?
Bash — для коротких скриптов из утилит (filter/transform/load пайплайны на logs). Python — для сложной логики, типизированных трансформаций, тестируемого кода. Граница условно — больше 50 строк → Python.
Чем xargs полезен?
Передаёт stdout как аргументы команде. find . -name '*.log' | xargs grep ERROR — grep по всем log-файлам. С -P N — параллельно. С -I {} — placeholder.
Что такое tee?
Разветвитель: cmd | tee file пишет stdout И в файл, И в следующий pipe. Полезно для логирования промежуточных результатов длинного pipeline.
Как ловить ошибки в bash?
set -euo pipefail в начале скрипта: e — выход на любой ошибке, u — ошибка на неопределённой переменной, o pipefail — ошибка в любом этапе pipe фейлит весь pipe.
Стоит ли учить awk глубоко?
Базовые awk '{print $N}', фильтры, агрегаты — must для DE. Полный язык awk (functions, arrays) — приятно знать, но 90% задач решаются 5-6 идиомами.
Это официальная информация?
Нет. Статья основана на man pages GNU coreutils и общей практике DevOps/DE.
Тренируйте Data Engineering — откройте тренажёр с 1500+ вопросами для собесов.