HuMan: cutАлексей Дмитриев, 10 декабря 2008Команда cut позволяет выбрать из каждой строки файла нужную часть (по единому правилу для всех строк) и показать выборку на экране дисплея. Команда имеет три основные опции:
Начнем с наиболее очевидного - символов (опция -с) Опция -сНапример, возьмем файл /etc/shells, в целом виде он выглядит так:
/bin/bash /bin/tcsh /bin/csh /bin/ash /bin/ksh /bin/zsh Теперь применим команду:
$ cut -c 1,5 /etc/shells // // // // // // В данном примере опция -c означает, что объектом выбора будут символы, 1,5 означает, что мы выбираем символы 1 и 5 (счет идет с 1), а все остальное содержимое файла игнорируется. Можно выбирать символы не по порядковым номерам, а диапазонами:
$ cut -c 1-5 /etc/shells /bin/ /bin/ /bin/ /bin/ /bin/ /bin/ В этом случае мы выбрали символы в диапазоне с 1 по 5 (включительно). Можно указать несколько диапазонов через запятую:
~$ cut -c 1-5,8-9 /etc/shells /bin/sh /bin/sh /bin/h /bin/h /bin/h /bin/h Первые три примера имеют чисто демонстрационный характер и не имеют практического смысла. Следующий пример может претендовать на некий смысл:
$ cut -c 6- /etc/shells bash tcsh csh ash ksh zsh Тут мы получили список доступных в системе шеллов. Для этого мы не стали указывать правую границу диапазона, что заставляет команду выдавать все содержимое строк от указанного символа до конца строки. Можно оставить прочерк с левой стороны, тогда выборка пойдет от начала строки до указанного символа. Интересно, что все эти примеры не всегда работают с русскими символами (в кодировке UTF-8, по крайней мере) - выдают какую-то странную ступенчатую распечатку:
$ cut -c 1- rus.txt йцукенгшщзхъ фывапролджэё ячсмитьбю.ёё Это полный текст файла rus.txt. Программа сработала правильно.
$ cut -c 1-5 rus.txt йц? фы? яч? $ А вот тут начались странности. Забавно, что даже следующее приглашение командной строки вышло по "лесенке". А вот в "настоящей" консоли, вызываемой нажатием Ctrl+Alt+F2, вывод той же команды выглядел более или менее прилично:
$ cut -c 1-5 rus.txt йц фы яч Как выяснилось в многочисленных опытах, символы кириллицы в кодировке UTF-8 состоят из двух байтов, поэтому нужно вводить удвоенные числовые значения. Скажем, если заменить в предыдущей команде 5 на 6 (или любое другое четное число), то и в эмуляторе консоли все будет как надо:
$ cut -c 1-6 rus.txt йцу фыв ячс Для чистоты эксперимента я запустил Knoppix5.1, у которого по умолчанию кодировка koi-8, так там никакой разницы с английским текстом не наблюдается - каждая буква представлена одним байтом:
$ cut -c 1-5 rus.txt йцуке фывап ячсми Так что с национальными кодировками ухо надо держать востро! Надеюсь, что с опцией -c ясность полная, можно переходить к следующей.
Опция -bВесьма похожа на предыдущую опцию, как по способу задания выборки байт, так и по результатам, ведь в большинстве случаев один байт определяет один символ.
$ cut -b 1-6 /etc/shells /bin/b /bin/t /bin/c /bin/a /bin/k /bin/z Мы выбрали первые 6 байт из каждой строки файла /etc/shells. Точно так же как и с опцией -с, можно использовать способы выборки n,m; -n; и n-. Остается лишь добавить, что символы табуляции и backspace (возврат назад на один символ с удалением его) трактуются как любой другой символ - они и занимают один байт. (Не поручусь за национальные кодировки).
Опция -fОбъектом выбора данной опции являются те самые загадочные "поля", о которых я говорил в предисловии. Оказалось все просто. Выбираем мы колонки текста, или столбцы, или что еще там, разделенные знаком табуляции. Так как я таких файлов никогда не встречал, то пришлось создать специально для опытов. Вот содержимое файла tab.txt:
qwer tyui op[] asdf ghjk llll zxcv bnm, .... А вот команда:
$ cut -f 1,2 tab.txt qwer tyui asdf ghjk zxcv bnm, Все как ожидалось, выбраны две первые колонки. Еще пример:
$ cut -f 2- tab.txt tyui op[] ghjk llll bnm, .... В общем понятно, схема та же, только с колонками. Вопрос в другом - где взять такие файлы с колонками, разделенными знаком табуляции, чтобы их обрабатывать? К счастью, есть опция -d, предназначенная для работы в паре с опцией -f и понимающая другие разделители текста, кроме знаков табуляции. В директории /etc полно файлов, содержащих столбцы данных, разделенных всякими разделителями; беда только, что они довольно длинные для примеров. Я возьму первые десять строчек из файла /etc/group и создам файл group10.txt.
$ cut -f 1- -d : group10.txt root::0:root bin::1:root,bin,daemon daemon::2:root,bin,daemon sys::3:root,bin,adm adm::4:root,adm,daemon tty::5: disk:!:6:root,adm,haldaemon,ya,alex lp::7:lp,ya,alex mem::8: kmem::9: В этом примере, опция -f приказывает отбирать все столбцы, с первого до последнего, а опция -d указывает на символ, являющийся разделителем -d : разделителем служит двоеточие. Выше на экране файл group10.txt полностью.
$ cut -f 1,3 -d : group10.txt root:0 bin:1 daemon:2 sys:3 adm:4 tty:5 disk:6 lp:7 mem:8 kmem:9 А сейчас мы отобрали первый и третий столбцы, то есть узнали идентификационный номер каждой группы. В остальном все те же правила выбора объекта, что и для прочих опций. Символы, разделяющие столбцы, разумеется, могут быть иными, нежели двоеточие. Их нужно задавать при помощи опции -d <символ>. Есть и более наглядный способ употребления опции -d. Вместо только что описанной конструкции (-d <символ>) пишем --delim=<символ>, это кажется более надежным, чем при помощи пробела. Остались две опции: -s и -n Опция -s употребляется с опцией -f и приказывает не выводить на экран строки, не содержащие символов-разделителей. Ясно даже мне.
Оставшиеся неясностиОпция -n осталась неопознанной мною. Она велит ничего не делать с многобайтными символами, в частности не разбивать их. Что это за символы я не знаю, как не знаю и того, что команда cut делает с ними по умолчанию. Есть и еще одна загадка. Как обозначить разделитель, если таковым является пробел? Или два-три пробела? Все мои эксперименты ни к чему не привели. Может кто-нибудь знает? Напишите мне, мой адрес в начале статьи.Внимание: Опции -c, -b, и -f могут употребляться только поодиночке. Опции --help и --version общеизвестны, и задерживаться на них я не буду.
Резюме программы cutПрограмма применима и эффективно работает с регулярными файлами, те есть с файлами, где из строчки в строчку повторяется некая структура информации (всякого рода списки, перечни, распечатки и прочее). Трудно представить себе, как ее можно использовать с обычным текстом, не разбитым на строки. Наличие трех подходов (байты, символы и столбцы) к определению выборки позволяют добиться успеха почти в любом случае, не одним способом, так другим. Особенно полезной может быть команда в качестве фильтра в составе программных каналов (pipes).
|