Как пользователи Linux, мы регулярно взаимодействуем с конфигурационными файлами, логами и скриптами. Одной из самых частых задач является фильтрация текста и извлечение нужных данных. Linux предоставляет мощный арсенал утилит командной строки для этих целей: grep, sed, awk. Однако для простых операций по нарезке строк идеально подходит cut.
В этой статье мы детально разберем утилиту cut, которая используется для удаления или, точнее, "вырезания" определенных секций из каждой строки файла. Она умеет фильтровать данные по позиции байта, символа или по разделителю (полям).
Мы рассмотрим работу команды на актуальных примерах. После прочтения вы сможете эффективно применять cut в своей повседневной работе.
Синтаксис команды
Синтаксис cut следует стандарту многих GNU-утилит:
cut <ОПЦИИ>... [ФАЙЛ]...
- <ОПЦИИ> — параметры, указывающие, как именно нужно резать текст (по байтам, символам или полям).
- [ФАЙЛ] — путь к файлу (или файлам), который нужно обработать. Если файл не указан, команда читает данные из стандартного ввода.
Для начала создадим тестовый файл distros.txt с актуальными версиями популярных дистрибутивов Linux. Мы будем использовать его во всех примерах.
$ cat > distros.txt <<EOF
Name Latest_Release Package_Manager
Ubuntu 24.04 apt
Red Hat 9.5 dnf
Debian 12.8 apt
Rocky Linux 9.5 dnf
Alma Linux 9.5 dnf
EOF
Вырезание по байтам (-b)
Команда cut позволяет извлекать данные, ориентируясь на их позицию в байтах. Для этого используется опция -b (bytes).
Извлечение одного байта
Давайте извлечем только первый байт каждой строки нашего файла:
$ cut -b 1 distros.txt
N
U
R
D
R
A
Поскольку в английском алфавите (ASCII) один символ равен одному байту, мы видим первые буквы названий.
Извлечение нескольких байтов
В предыдущем примере мы увидели, как выбрать один байт из файла. Однако команда вырезания также позволяет нам выбирать несколько байтов с помощью запятой.
Мы можем выбрать конкретные байты, перечислив их через запятую. Например, выберем 1-й, 2-й, 3-й и 4-й байты:
$ cut -b 1,2,3,4 distros.txt
Name
Ubun
Red
Debi
Rock
Alma
Диапазон байтов
Если нужно вырезать длинный кусок, перечислять каждый байт неудобно. Используйте дефис - для задания диапазона. Вырежем первые 12 байтов (названия дистрибутивов):
$ cut -b 1-12 distros.txt
Name
Ubuntu
Red Hat
Debian
Rocky Linux
Alma Linux
Также можно указывать диапазон из середины строки. Например, байты с 17-го по 30-й (где у нас версии):
$ cut -b 17-30 distros.txt
Latest_Release
24.04
9.5
12.8
9.5
9.5
Открытые диапазоны
Иногда мы не знаем точную длину строки, но знаем, откуда начать или где закончить.
- От N до конца строки: N-
- От начала строки до N: -N
Пример вывода всего текста, начиная с 17-го байта:
$ cut -b 17- distros.txt
Latest_Release Package_Manager
24.04 apt
9.5 dnf
12.8 apt
9.5 dnf
9.5 dnf
Пример вывода от начала строки до 12-го байта:
$ cut -b -12 distros.txt
Name
Ubuntu
Red Hat
Debian
Rocky Linux
Alma Linux
Вырезание по символам (-c) и проблема UTF-8
Опция -c (characters) предназначена для фильтрации по символам. В старых однобайтовых кодировках (ASCII) она работает идентично -b. Однако в современном мире правит UTF-8, где один символ (например, кириллица) может занимать 2 байта и более.
Здесь кроется важный нюанс: стандартная версия cut (из пакета GNU Coreutils) часто обрабатывает опцию -c как байты, если не наложены специфические патчи.
Попробуем вырезать 3-й символ из слова roаdit, где буква "а" написана кириллицей (она занимает 2 байта):
$ echo roаdit | cut -b 3
�
Мы получили "битый" символ (знак вопроса или кракозябру), потому что cut разрезал двухбайтовую букву "а" посередине.
Попробуем теперь опцию -c. Если ваш cut не поддерживает мультибайтовые символы полноценно (как, например, в большинстве версий Ubuntu/Debian "из коробки"), результат может быть таким же печальным, или вы получите не тот символ, который ожидали.
$ echo roаdit | cut -c 3
Примечание: Если вы видите корректный символ, значит ваша версия cut или настройки локали умеют корректно работать с UTF-8. Но полагаться на это в скриптах рискованно.
Как быть с Unicode? Если вам нужно надежно работать с кириллицей или эмодзи, лучше использовать awk, который корректно понимает символы UTF-8:
$ echo roаdit | awk '{print substr($0, 3, 1)}'
а
Вырезание по разделителю (-d) и полям (-f)
Это, пожалуй, самый полезный режим работы cut. Он позволяет разбирать структурированные данные, такие как CSV, /etc/passwd или логи.
- -d (delimiter) — задает разделитель (по умолчанию это табуляция TAB).
- -f (field) — номер поля, которое нужно извлечь.
В нашем файле distros.txt колонки визуально выровнены пробелами, но количество пробелов разное. cut плохо работает с "плавающим" количеством пробелов. Для примера предположим, что данные разделены одиночными табуляциями или переформатируем вывод.
Для наглядности используем системный файл /etc/passwd, где разделителем является двоеточие :.
Выведем список всех пользователей (1-е поле):
$ cut -d ":" -f 1 /etc/passwd | head -n 5
root
daemon
bin
sys
sync
А теперь выведем имя пользователя (1-е поле) и его домашнюю директорию (6-е поле):
$ cut -d ":" -f 1,6 /etc/passwd | head -n 5
root:/root
daemon:/usr/sbin
bin:/bin
sys:/dev
sync:/bin
Инверсия выбора (--complement)
Иногда проще сказать, что нам не нужно, чем перечислять все, что нужно. Опция --complement выводит всё, кроме указанных полей или байтов.
Вернемся к нашему файлу distros.txt. Допустим, мы хотим вывести всё, кроме первого символа каждой строки:
$ cut -c 1 --complement distros.txt
ame Latest_Release Package_Manager
buntu 24.04 apt
ed Hat 9.5 dnf
ebian 12.8 apt
ocky Linux 9.5 dnf
lma Linux 9.5 dnf
Это также отлично работает с полями (-f). Если у вас есть CSV файл из 10 колонок, и вы хотите убрать только вторую, используйте --complement -f 2.
Заключение
Команда cut — это простой, но эффективный инструмент в арсенале администратора и разработчика. Она идеально подходит для быстрой обработки структурированных данных с предсказуемыми разделителями.
Краткая шпаргалка:
- cut -b 1-5 — вырезать байты с 1 по 5.
- cut -d ":" -f 1 — вырезать первое поле, используя : как разделитель.
- cut -c — использовать с осторожностью на кириллице (лучше взять awk).
- --complement — инвертировать выбор.
Знаете интересные примеры использования cut в своих скриптах? Поделитесь ими в комментариях!