Поиск по сайту:

Как использовать команду Linux cut


Команда Linux cut позволяет извлекать фрагменты текста из файлов или потоков данных. Это особенно полезно для работы с данными с разделителями, такими как файлы CSV. Вот что вам нужно знать.

Команда вырезания

Команда cut — ветеран мира Unix, дебютировавший в 1982 году как часть AT&T System III UNIX. Его цель в жизни — вырезать фрагменты текста из файлов или потоков в соответствии с установленными вами критериями. Его синтаксис так же прост, как и его цель, но именно эта совместная простота делает его таким полезным.

Используя проверенный временем способ UNIX, комбинируя cut с другими утилитами, такими как grep, вы можете создавать элегантные и эффективные решения сложных проблем. Хотя существуют разные версии cut, мы собираемся обсудить стандартную версию GNU/Linux. Имейте в виду, что другие версии, особенно cut в вариантах BSD, не включают все описанные здесь параметры.

Вы можете проверить, какая версия установлена на вашем компьютере, введя эту команду:

cut --version

Если вы видите «GNU coreutils» в выводе, вы используете версию, которую мы собираемся описать в этой статье. Все версии cut имеют некоторые из этих функций, но в версию для Linux были добавлены улучшения.

Первые шаги с вырезом

Независимо от того, передаем ли мы информацию в cut или используем cut для чтения файла, команды, которые мы используем, одинаковы. Все, что вы можете сделать с потоком ввода с помощью cut, можно сделать со строкой текста из файла и наоборот. Мы можем указать cut работать с байтами, символами или полями с разделителями.

Чтобы выбрать один байт, мы используем параметр -b (byte) и сообщаем cut, какой байт или байты нам нужны. В данном случае это пятый байт. Мы отправляем строку «how-to geek» в команду cut с вертикальной чертой «|» из echo.

echo 'how-to geek' | cut -b 5

Пятый байт в этой строке — «t», поэтому cut в ответ печатает «t» в окне терминала.

Для указания диапазона используется дефис. Чтобы извлечь байты с 5 по 11 включительно, мы должны выполнить эту команду:

echo 'how-to geek' | cut -b 5-11

Вы можете указать несколько отдельных байтов или диапазонов, разделив их запятыми. Чтобы извлечь байт 5 и байт 11, используйте эту команду:

echo 'how-to geek' | cut -b 5,11

Чтобы получить первую букву каждого слова, мы можем использовать эту команду:

echo 'how-to geek' | cut -b 1,5,8

Если вы используете дефис без первого числа, cut возвращает все, начиная с позиции 1 и заканчивая номером. Если вы используете дефис без второго числа, cut возвращает все от первого числа до конца потока или строки.

echo 'how-to geek' | cut -b -6
echo 'how-to geek' | cut -b 8-

Использование вырезания с символами

Использование cut с символами почти такое же, как и с байтами. В обоих случаях необходимо соблюдать особую осторожность со сложными символами. Используя параметр -c (character), мы указываем cut работать с символами, а не с байтами.

echo 'how-to geek' | cut -c 1,5,8
echo 'how-to geek' | cut -c 8-11

Они работают именно так, как вы ожидаете. Но взгляните на этот пример. Это слово состоит из шести букв, поэтому запрос cut на возврат символов от одного до шести должен вернуть слово целиком. Но это не так. Это короткий символ. Чтобы увидеть слово целиком, мы должны запросить символы от одного до семи.

echo 'piñata' | cut -c 1-6
echo 'piñata' | cut -c 1-7

Проблема в том, что символ «ñ» на самом деле состоит из двух байтов. Мы можем увидеть это довольно легко. У нас есть короткий текстовый файл, содержащий эту строку текста:

cat unicode.txt

Мы изучим этот файл с помощью утилиты hexdump. Использование параметра -C (канонический) дает нам таблицу шестнадцатеричных цифр с эквивалентом ASCII справа. В таблице ASCII «ñ» не отображается, вместо этого есть точки, представляющие два непечатаемых символа. Это байты, выделенные в шестнадцатеричной таблице.

hexdump -C unicode.txt

Эти два байта используются программой отображения — в данном случае оболочкой Bash — для идентификации «ñ». Многие символы Unicode используют три или более байтов для представления одного символа.

Если мы запрашиваем символ 3 или символ 4, нам показывают символ непечатаемого символа. Если мы запросим байты 3 и 4, оболочка интерпретирует их как «ñ».

echo 'piñata' | cut -c 3
echo 'piñata' | cut -c 4
echo 'piñata' | cut -c 3-4

Использование cut с данными с разделителями

Мы можем попросить cut разделить строки текста, используя указанный разделитель. По умолчанию cut использует символ табуляции, но легко указать ему использовать все, что мы хотим. Поля в файле «/etc/passwd» разделены двоеточием «:», поэтому мы будем использовать его в качестве разделителя и извлечем некоторый текст.

Части текста между разделителями называются полями и упоминаются так же, как байты или символы, но им предшествует параметр -f (поля). Вы можете оставить пробел между «f» и цифрой или нет.

Первая команда использует параметр -d (разделитель), чтобы указать cut использовать «:» в качестве разделителя. Он будет извлекать первое поле из каждой строки в файле «/etc/passwd». Это будет длинный список, поэтому мы используем head с опцией -n (число), чтобы показать только первые пять ответов. Вторая команда делает то же самое, но использует tail, чтобы показать нам последние пять ответов.

cut -d':' -f1 /etc/passwd | head -n 5
cut -d':' -f2 /etc/passwd | tail -n 5

Чтобы извлечь выбранные поля, перечислите их в виде списка, разделенного запятыми. Эта команда извлечет поля с первого по третье, пятое и шестое.

cut -d':' -f1-3,5,6 /etc/passwd | tail -n 5

Включив grep в команду, мы можем искать строки, содержащие «/bin/bash». Это означает, что мы можем перечислить только те записи, для которых Bash является оболочкой по умолчанию. Обычно это «обычные» учетные записи пользователей. Мы будем запрашивать поля от одного до шести, потому что седьмое поле — это поле оболочки по умолчанию, и мы уже знаем, что это такое — мы ищем его.

grep "/bin/bash" /etc/passwd | cut -d':' -f1-6

Другой способ включить все поля, кроме одного, — использовать параметр --complement. Это инвертирует выбор поля и показывает все, что не было запрошено. Давайте повторим последнюю команду, но попросим только седьмое поле. Затем мы снова запустим эту команду с опцией --complement.

grep "/bin/bash" /etc/passwd | cut -d':' -f7
grep "/bin/bash" /etc/passwd | cut -d':' -f7 --complement

Первая команда находит список записей, но седьмое поле не дает нам ничего, чтобы различать их, поэтому мы не знаем, к кому относятся записи. Во второй команде, добавив параметр --complement, мы получаем все, кроме седьмого поля.

Вырез трубопровода В разрез

Придерживаясь файла «/etc/passwd», давайте извлечем пятое поле. Это фактическое имя пользователя, которому принадлежит учетная запись пользователя.

grep "/bin/bash" /etc/passwd | cut -d':' -f5

Пятое поле имеет подполя, разделенные запятыми. Они редко заполняются, поэтому они отображаются в виде строки запятых.

Мы можем удалить запятые, направив вывод предыдущей команды в другой вызов cut . Во втором экземпляре cut в качестве разделителя используется запятая ,. Опция -s (только с разделителями) сообщает cut, что следует подавлять результаты, в которых вообще нет разделителя.

grep "/bin/bash" /etc/passwd | cut -d':' -s -f5 | cut -d',' -s -f1

Поскольку корневая запись не имеет подполей с запятыми в пятом поле, она подавляется, и мы получаем нужные результаты — список имен «настоящих» пользователей, настроенных на этом компьютере.

Выходной разделитель

У нас есть небольшой файл с некоторыми значениями, разделенными запятыми. Поля в этих фиктивных данных:

  • ID: идентификационный номер базы данных
  • Имя: имя субъекта.
  • Фамилия: фамилия субъекта.
  • email: их адрес электронной почты.
  • IP-адрес: их IP-адрес.
  • Бренд: марка автомобиля, на котором они ездят.
  • Модель: модель автомобиля, которым они управляют.
  • Год: год выпуска автомобиля.

cat small.csv

Если мы укажем cut использовать запятую в качестве разделителя, мы сможем извлекать поля так же, как и раньше. Иногда вам потребуется извлечь данные из файла, но вы не хотите, чтобы разделитель полей был включен в результаты. Используя --output-delimiter, мы можем указать cut, какой символ — или фактически последовательность символов — использовать вместо фактического разделителя.

cut -d ',' -f 2,3 small.csv
cut -d ',' -f 2,3 small.csv --output-delimiter=' '

Вторая команда указывает cut заменить запятые пробелами.

Мы можем пойти дальше и использовать эту функцию для преобразования вывода в вертикальный список. Эта команда использует символ новой строки в качестве выходного разделителя. Обратите внимание на «$», который нам нужно включить, чтобы символ новой строки действовал, а не интерпретировался как буквальная последовательность из двух символов.

Мы будем использовать grep, чтобы отфильтровать запись для Морганы Ренвик, и попросим cut напечатать все поля от поля два до конца записи и использовать новую строку символ в качестве выходного разделителя.

grep 'renwick' small.csv | cut -d ',' -f2- --output-delimiter=$''

Олди, но Голди

На момент написания этой статьи маленькой команде cut исполнилось 40 лет, и мы все еще используем ее и пишем о ней сегодня. Я полагаю, что нарезка текста сегодня такая же, как и 40 лет назад. То есть намного проще, когда у вас есть нужный инструмент под рукой.