Эта заметка доступна на: English Castellano Deutsch Francais Nederlands Russian Turkce |
Автор Manuel Muriel Cordero Об авторе : Manuel Muriel Cordero учится в Университете Севильи на факультете Информатики и статистики Содержание: |
Резюме:
Предыдущая заметка из этой серии ( Basic UNIX commands) была обзорной по ОС Linux - мы рассмотрели основы этой операционной системы. Следующим шагом будет изучение команд Unix, которые в сочетании с оболочкой позволяют более эффективно управлять файлами и самой ОС, что мы и сделаем в данной заметке.
Перед изучением команд сделаем небольшое отступление и перечислим некоторые факты из их истории. Ken Thompsom и Denis Ritchie, создавая ОС Unix в начале 70-х, старались сделать ее удобной для программистов. Одним из решений было создание набора инструментов, небольших по объему, для решения специфических задач. Решение более сложных задач осуществлялось посредством взаимодействия этих инструментов, при котором результаты действия одной команды становились исходными данными для другой.
Такое взаимодействие доступно благодаря наличию конвейеров и перенаправления результатов работы ( см. в предыдущей заметке ).
Продемонстрируем это на простом примере :
$ who | grep pepe
who и grep две разные команды объединенные конвейером "|". who выводит список всех пользователей, работающих в данный момент на компьютере :
$ who manolo tty1 Dec 22 13:15 pepe ps/2 Dec 22 14:36 root tty2 Dec 22 10:03 pepe ps/2 Dec 22 14:37
Результатом являются строки, состоящие из 4-х полей, разделенные символом табуляции : имя пользователя, терминал, дата и время подключения.
"grep pepe" выбирает только строки, содержащие "pepe".
$ who | grep pepe pepe ps/2 Dec 22 14:36 pepe ps/2 Dec 22 14:37
Возможно ваша задача проще - кто-нибудь вообще работает на компьютере или нет? Подходящая команда wc.
wc - подсчитывает количество символов, слов или строк. В нашем случае подходит опция для посчета строк -l.
$ who | wc -l 4 $ who | grep pepe | wc -l 2
Четверо работают на компьютере в общем и в частности pepe на 2 терминалах.
Проверим работает ли antonio :
$ who | grep antonio | wc -l 0
Основатель проекта GNU Richard Stallman поднял вопрос о контроле развития компьютерной науки несколькими крупными компаниями, что затрудняет ее естественное развитие. Некоторые крупные коммерческие фирмы взяли за основу редактор emacs, разработанный в MIT, и создали свои собственные редакторы, и это уже было неприятным фактом. Этот случай положил начало нового проекта, в рамках которого все исходные тексты становились доступными всем. Этот проект получил название GNU, стратегической целью которого было создание ОС с открытым кодом. Первыми шагами были новый emacs, компилятор c ( gcc ) и несколько инструментов для Unix систем. Эти инструменты и рассматриваются в данной заметке.
Наш первый пример был более общим, сейчас рассмотрим более подробно.
Синтаксис :
$ grep [-options] pattern files
Наиболее часто используемые опции :
-n печатать номер строки
-c печатать колическтво обнаруженных совпадений
-v поиск строк не содержащих заданного шаблона
Шаблон - набор символов для поиска. Если шаблон содержит пробел - необходимо поместить его в кавычки ( " ) :
$ grep "Hola mundo" file.txt
Если мы ищем строки, содержащие wildcards, апострофы, кавычки или slash - они должны быть помещены в кавычки или перед таким символом надо использовать так называемый escape - символ '\' для исключения обработки данного символа оболочкой.
$ grep \*\"\'\?\< file.txt Результат : Esto es una cadena chunga -> *"'?<
grep и другие GNU утилиты позволяют выполнять более сложный поиск, благодаря
регулярным выражениям, которые схожи с wildcards оболочки в смысле того, что
могут заменять символы или группы символов. В конце заметки в разделе "
ссылки" есть адрес отдельной заметки посвященной регулярным выражениям.
Несколько примеров :
$ grep c.nпоиск любого вхождения строки, состоящей из "c", любого символа и "n".
$ grep "[Bc]el"поиск любого вхождения "Bel" или "cel".
$ grep "[m-o]ata"поиск любого вхождения из mata, nata или oata.
$ grep "[^m-o]ata"поиск любого вхождения строки, заканчивающейся на ata и не содержащей символы "m", "n" или "o" в качестве первой буквы.
$ grep "^Martin come"поиск строки, начинающейся с "Martin come". Так как символ ^ не заключен в квадратные скобки - он обозначает начало строки.
$ grep "durmiendo$"поиск строк, заканчивающихся на "durmiendo". Символ $ обозначает конец строки.
$ grep "^Caja San Fernando gana la liga$"поиск строк точно совпадающих с заданной.
Как было сказано ранее - для поиска специальных символов необходимо использовать "\" :
$ grep "E\.T\."поиск "E.T.".
Команда применяется для поиска файлов. Ранее уже была написана заметка в журнале LinuxFocus об этой команде и самое лучшее что мы можем сделать - дать ссылку на нее.
Информация в ОС Unix хранится в ASCII файлах, в которых строки и поля разделяются специальными символами - такими как табуляция или двоеточие. Иногда бывает необходимо часть одного файла вставить в другой. Команды cut и paste как раз и предназначены для этого.
Рассмотрим на примере файла /etc/passwd : каждая строка состоит из семи полей, разделенных двоеточием - имя пользователя, пароль, идентификатор пользователя, идентификатор группы, персональная информация, домашний каталог и shell.
Пример такого файла :
root:x:0:0:root:/root:/bin/bash murie:x:500:500:Manuel Muriel Cordero:/home/murie:/bin/bash practica:x:501:501:Usuario de practicas para Ksh:/home/practica:/bin/ksh wizardi:x:502:502:Wizard para nethack:/home/wizard:/bin/bash
Если мы хотим получить имя пользователя и его shell - необходимо взять информацию из полей 1 и 7 :
$ cut -f1,7 -d: /etc/passwd root:/bin/bash murie:/bin/bash practica:/bin/ksh wizard:/bin/bashОпция -f определяет поля, -d - разделитель ( по умолчанию символ табуляции ) и завершается команда именем файла для обработки.
Кроме того можно определить набор полей :
$ cut -f5-7 -d: /etc/passwd root:/root:/bin/bash Manuel Muriel Cordero:/home/murie:/bin/bash Usuario de practicas para Ksh:/home/practica:/bin/ksh Wizard para nethack:/home/wizard:/bin/bash
Если мы сохранили работу каких - либо команд с помощью ">" в два разных файла, а теперь нам необходимо соединить их - используем команду paste :
$ paste output1 output2 root:/bin/bash:root:/root:/bin/bash murie:/bin/bash:Manuel Muriel Cordero:/home/murie:/bin/bash practica:/bin/ksh:Usuario de practicas para Ksk:/home/practica:/bin/ksh wizard:/bin/bash:Wizard para nethack:/home/wizard:/bin/bash
Допустим нам надо отсортировать файл /etc/passwd по полю с персональной информацией - применим команду sort :
$ sort -t: +4 /etc/passwd murie:x:500:500:Manuel Muriel Cordero:/home/murie:/bin/bash practica:x:501:501:Usuario de practicas para Ksh:/home/practica:/bin/ksh wizard:x:502:502:Wizard para nethack:/home/wizard:/bin/bash root:x:0:0:root:/root:/bin/bash
Нетрудно заметить, что файл был отсортирован в соответствии с таблицей ASCII символов. Чтобы игнорировать регистр символов - используем следующую команду :
$ sort -t: +4f /etc/passwd murie:x:500:500:Manuel Muriel Cordero:/home/murie:/bin/bash root:x:0:0:root:/root:/bin/bash practica:x:501:501:Usuario de practicas para Ksh:/home/practica:/bin/ksh wizard:x:502:502:Wizard para nethack:/home/wizard:/bin/bash
Опция -t определяет разделитель, +4 - номер поля по которому будет проводиться сортировка, f - игнорировать регистр.
Усложним пример - отсортируем файл сначала по полю, определяющему shell, а затем по полю с персональной информацией :
$ sort -t: +6r +4f /etc/passwd practica:x:501:501:Usuario de practicas para Ksh:/home/practica:/bin/ksh murie:x:500:500:Manuel Muriel Cordero:/home/murie:/bin/bash root:x:0:0:root:/root:/bin/bash wizard:x:502:502:Wizard para nethack:/home/wizard:/bin/bash
Еще пример - у вас есть файл с персонами, которым вы одолжили деньги и соответствующие суммы :
Son Goku:23450 Son Gohan:4570 Picolo:356700 Ranma 1/2:700
Попробуем найти наиболее важную персону :
$ sort +1 deudas Ranma 1/2:700 Son Gohan:4570 Son Goku:23450 Picolo:356700Так как количество полей не одинаковое - результат немного не тот на который мы рассчитывали. Решением этой проблемы станет опция -n команды sort :
$ sort +1n deudas Picolo:356700 Son Goku:23450 Son Gohan:4570 Ranma 1/2:700
Рассмотрим опции команды :
+n.m перейти через n полей и m символов перед выполнением команды;
-n.m остановить сортировку при достижении m символа в n поле;
-b игнорировать пробелы и знаки табуляции в начале строки
-d сортировать используя только буквы, цифры и пробелы
-f игнорировать регистр
-n сортировать по номерам строк
-r обратный порядок сортировки
Как мы уже упоминали ранее wc - счетчик символов, слов и строк. По умолчанию результатом выполнения команды является отображение количества символов, слов и строк в заданном файле.
Рассмотрим опции :
-l только строки
-w только слова
-c только символы
Иногда необходимо знать в чем состоит различие двух версий одного и того же файла. Например в программировании - над проектом работает много людей и необходимо отслеживать внесенные изменения в исходный код. Рассмотрим команды предназначенные для решения этой задачи.
Начнем с cmp - сравнивает два файла и выдает информацию о первом обнаруженном отличии ( в формате : номер символа и строки ) :
$ cmp old new old new differ: char 11234, line 333
Следующая команда comm - выдает информацию в следующем формате : первое
значение - количество уникальных строк 1-го файла, второе - количество
уникальных строк 2-го файла, третье - количество совпадающих строк.
С помощью опций -1, -2 и -3 можно отключить вывод информации по одной из
колонок. Следующий пример демонстрирует использование команды comm для
получения информации об уникальных строках 1-го файла и совпадающих строках.
$ comm -2 old new
И наконец команда diff - основная для сложных задач. Если вы хотите установить новое ядро - вы загружаете исходные тексты нового ядра или патч, который значительно меньше в объеме. Обычно патч имеет суффикс diff. Использование патча предпочтительнее - вы загружаете меньше файлов ( только изменения ), изменяете свои файлы в соответствии с патчем и компилируете. Без опций команда выдает информацию о том, какие изменения следует сделать чтобы файлы стали одинаковыми.
$ diff old new 3c3 < The Hobbit --- > The Lord of the Rings 78a79,87 >Three Rings for the Elven-kings under the sky, >Seven for the Dwarf-lords in their halls of stone, >Nine for Mortal Men doomed to die, >One for the Dark Lord on his dark throne >In the Land of Mordor where the Shadows lie. >One Ring to rule them all, One Ring to find them, >One Ring to bring them all and in the darkness bind them >In the Land of Mordor where the Shadows lie.
3c3 обозначает, что необходимо изменить 3 строки заменив в них "The Hobbit" на "The Lord of the Rings", 78a79,87 определяет строки для изменения.
Команда uniq мспользуется для вывода только уникальных значений. Например нам необходимо получить информацию о работающих сейчас на компьютере, для этого мы используем команды who и cut.
$ who | cut -f1 -d' ' root murie murie practica
Теперь нам необходимо выполнить команду, которая выводила бы только уникальные имена ( без повторений ) :
$ who | cut -f1 -d' ' | sort | uniq murie practica root
Опция -d' ' определяет разделителем пробел, потому что команда who использует пробел вместо символа табуляции.
Команда uniq сравнивает только соседние строки. В нашем примере "murie" появляются одна за другой, но могло быть иначе. Это обстоятельство и объясняет использование нами команды sort.
sed - потоковый редактор, один из самых популярных инструментов Unix. Используя синтаксис sed можно создавать и использовать командные файлы, что-то вроде batch файлов MS-DOS. Возможности этого редактора довольно широки и их рассмотрение сделало бы данную заметку очень объемной. Поэтому мы лишь кратко рассмотрим основы sed, а любознательный пользователь может самостоятельно изучить man и info pages.
Синтаксис :
$ sed 'command' files
Рассмотрим пример, в котором мы меняем все "Manolo" на "Fernando" в файле :
$ sed 's/Manolo/Fernando/g' file
Результат выводится через стандартный поток вывода, следоватеьно для его сохранения можно использовать ">".
Многие наверное увидели сходство с командой редактора vi search & replace. На самом деле большинство команд ":" ( обращение к ex ) являются командами к sed.
Обычное использование sed сводится к следующему : определяется диапазон для
изменения и применяемая команда. Диапазон может быть строкой, набором строк
или шаблоном.
Некоторые команды :
Команда Действие ------- ------ a\ добавить строку после адресованных c\ изменить адресованные строки d удалить строку(и) g заменить все i\ вставить строки p вывести строку q завершить после достижения адресной строки r file читать файл s/one/two заменить "one" на "two" w file записать в файл по указанному адресу = выводить номер текущей строки ! command применить команду к адресной строке
Использовать sed можно определив строку или набор строк :
$ sed '3d' fileудалит третью строку в файле
$ sed '2,4s/e/#/' fileзаменит первое вхождение символа "e" на символ "#" в строках 2-4 включительно,
или шаблон :
$ sed '/[Qq]ueen/d' songsудалит все строки содержащие "Queen" или "queen".
Если необходимо удалить пустые строки, подойдет следующая команда :
$ sed '/^$/d' fileно в данном случае не будут удалены строки состоящие из пробелов. Следующая команда решит и эту проблему :
$ sed '/^ *$/d' fileгде "*" обозначает любое количество предыдущего символа, в нашем случае это пробел - " ".
$ sed '/InitMenu/a\ > the text to append' file.txtВ следующем примере мы ищем строку, содержащую "InitMenu" и добавляем новую строку после нее. Этот пример работает только в оболочках bash или sh. Сначала вы вводите все до a\ включительно, нажимаете Enter и набираете остальное.
Tcsh воспринимает символ новой строки в одинарных кавычках по - другому, поэтому рекомендуется использовать двойные кавычки.
$ sed '/InitMenu/a\ ? the text to append' file.txtСимвол ? аналогичен > в оболочке bash.
Название awk происходит от имен разработчиков : Alfred Aho Peter Weinberger и Brian Kernighan.
awk одна из интереснейших утилит Unix, с ее помощью решается множество разнообразных задач.
Также необходимо заметить, что sed и awk - основа большинства shell - скриптов. Решения с помощью этих утилит впечатляют, особенно если брать во внимание, что не используются компилируемые языки, такие как С. Например установочная программа дистрибутива SlackWare Linux - shell - скрипт или еще пример - множество cgi - программ также shell - скрипты.
В наши дни утилиты командной строки используются все меньше из - за применения графического интерфейса. Немаловажно и появление языка PERL - многие shell - скрипты были заменены PERL - скриптами. Создается впечатление, что скоро утилиты командной строки вообще перестанут использовать. Тем не менее из моего опыта следует, что множество задач можно решить несколькими строками shell - скрипта. Кроме того ваша работа будет более эффективной если вы знаете как использовать эти команды в сочетании с оболочкой.
Рассмотрим небольшой пример. Возьмем файл "sales", в котором содержится информация о купленных продуктах, их количестве и цене за единицу :
oranges 5 250 peras 3 120 apples 2 360
Файл состоит из 3-х строк, поля которых разделены символом табуляции. Создадим 4-ое поле, содержащее общую сумму для каждого продукта :
$ awk '{total=$2*$3; print $0 , total }' sales oranges 6 250 1250 peras 3 120 360 apples 2 360 720
Переменная total содержит информацию для 4-го поля. После вычисления - выводится исходная строка и переменная total.
awk прекрасно подходит для решения задач при работе с текстовыми файлами. Советую вам обратить внимание на man и info pages, если вам понравилась эта утилита.
Shell - скрипты - последовательность команд, собранных в файл.
Их можно сравнить с batch файлами DOS, но shell - скрипты более мощные.
Shell - скрипты конечно работают с передаваемыми аргументами, которые воспринимаются как переменные $0 ( имя самого файла ), $1, $2, ... $9. Все аргументы содержатся в переменной $*.
Shell - скрипты можно создать с помощью любого текстового редактора. Для выполнения shell - скрипта используйте следующую команду :
$ sh shell-scriptИли можно сделать скрипт исполняемым с помощью команды :
$ chmod 700 shell-scriptи выполнить следующим образом :
$ shell-script
На этом мы заканчиваем заметку и разговор о shell - скриптах. В следующей заметке рассмотрим текстовые редакторы Unix - vi & emacs. Это необходимые программы для каждого пользователя Linux.
Это ознакомительная заметка. Более подробная информация о рассмотренных утилитах в других заметках журнала LinuxFocus :
|
Webpages maintained by the LinuxFocus Editor team
© Manuel Muriel Cordero, FDL LinuxFocus.org Click here to report a fault or send a comment to Linuxfocus |
Translation information:
|
2000-11-03, generated by lfparser version 1.9