cut
Вырезать из каждой строки столбцы по разделителю или символы по позиции
cut печатает из каждой строки только выбранные части: поля, разделённые одним символом, или диапазон позиций. Это самый простой способ взять столбец из файла с чётким разделителем — /etc/passwd, CSV без кавычек, TSV.
Синтаксис
cut -d 'разделитель' -f список [файл…]
cut -c список [файл…]
cut -b список [файл…]
Нужна ровно одна из опций -f, -c, -b. Без файлов (или с файлом -) читается stdin.
Опции
| Опция | Что делает |
|---|---|
-f список | выбрать поля |
-d 'c' | разделитель полей — один символ; по умолчанию табуляция |
-s | пропускать строки, где разделителя нет вовсе (по умолчанию они печатаются целиком) |
-c список | выбрать символы по позициям (в GNU cut — фактически байты, как -b) |
-b список | выбрать байты по позициям |
--complement | вывести всё, кроме выбранного |
--output-delimiter='STR' | чем соединять выбранные поля или диапазоны на выходе (по умолчанию — входным разделителем) |
-z | строки разделены нулевым байтом, а не \n |
Как записывается список
| Запись | Что значит |
|---|---|
3 | третье поле (позиция) |
1,3,5 | несколько через запятую |
2-4 | со 2-го по 4-е включительно |
3- | с 3-го до конца строки |
-2 | с 1-го по 2-е |
1,4- | можно сочетать |
Нумерация с 1. Выбранное печатается в порядке следования в строке и только один раз, как бы ни был записан список.
Примеры
# имя пользователя и оболочка из /etc/passwd
cut -d: -f1,7 /etc/passwd
# все поля начиная со второго
echo 'a:b:c:d' | cut -d: -f2-
# всё, кроме второго поля
echo 'a:b:c:d' | cut -d: --complement -f2
# поменять разделитель на выходе
echo 'a:b:c' | cut -d: -f1,3 --output-delimiter=' '
# первые 3 символа каждой строки; всё с 5-го символа
echo 'hello world' | cut -c1-3
echo 'hello world' | cut -c5-
# TSV: разделитель по умолчанию — табуляция
printf 'id\tname\n1\talice\n' | cut -f2
# CSV без кавычек внутри значений
printf 'x,10\ny,20\n' | cut -d, -f2
# только строки, где разделитель есть
printf 'a:b\nno-delimiter\n' | cut -s -d: -f2
# вывод с выравниванием пробелами: сначала сжать пробелы
printf 'a 1\nbb 2\n' | tr -s ' ' | cut -d' ' -f2
Подводные камни
- Разделитель — ровно один символ. Несколько пробелов подряд дают пустые поля: в
a bполе 2 пустое, аb— третье. Для вывода вродеls -lилиpsсожми пробелы черезtr -s ' 'или возьми awk, который делит по любой цепочке пробелов. - Многосимвольный разделитель не поддерживается.
cut -d'::'завершится ошибкойthe delimiter must be a single character. - Порядок полей не меняется.
-f3,1выведет поля в порядке 1, 3. Чтобы переставить столбцы, нужен awk. - Строки без разделителя печатаются целиком.
echo nodelim | cut -d: -f2выведетnodelim. Добавь-s, чтобы их пропускать. -cсчитает байты. В GNU cut-cработает как-b, поэтому кириллическая буква (2 байта в UTF-8) режется пополам.- CSV с кавычками (
"Иванов, И.",42)cutне понимает: запятая внутри кавычек тоже станет разделителем. - Пробел в начале строки — тоже граница поля. В
a bс-d' 'первое поле пустое.