Home Map Index Search News Archives Links About LF
[Top bar]
[Bottom bar]
эта страница доступна на следующих языках: English  Castellano  Deutsch  Francais  Nederlands  Russian  Turkce  

[Foto del Autor]
Автор Manuel Muriel Cordero

Об авторе :
Manuel Muriel Cordero учится в Университете Севильи на факультете Информатики и статистики

Содержание:

GNU утилиты

[Ilustracion]

Резюме:

Предыдущая заметка из этой серии ( 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 утилиты

Основатель проекта GNU Richard Stallman поднял вопрос о контроле развития компьютерной науки несколькими крупными компаниями, что затрудняет ее естественное развитие. Некоторые крупные коммерческие фирмы взяли за основу редактор emacs, разработанный в MIT, и создали свои собственные редакторы, и это уже было неприятным фактом. Этот случай положил начало нового проекта, в рамках которого все исходные тексты становились доступными всем. Этот проект получил название GNU, стратегической целью которого было создание ОС с открытым кодом. Первыми шагами были новый emacs, компилятор c ( gcc ) и несколько инструментов для Unix систем. Эти инструменты и рассматриваются в данной заметке.

 

grep

Наш первый пример был более общим, сейчас рассмотрим более подробно.

Синтаксис :

$ 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.".

 

Find

Команда применяется для поиска файлов. Ранее уже была написана заметка в журнале LinuxFocus об этой команде и самое лучшее что мы можем сделать - дать ссылку на нее.

 

cut & paste

Информация в ОС 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

 

sort

Допустим нам надо отсортировать файл /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

Как мы уже упоминали ранее wc - счетчик символов, слов и строк. По умолчанию результатом выполнения команды является отображение количества символов, слов и строк в заданном файле.

Рассмотрим опции :

-l только строки
-w только слова
-c только символы

 

cmp, comm, diff

Иногда необходимо знать в чем состоит различие двух версий одного и того же файла. Например в программировании - над проектом работает много людей и необходимо отслеживать внесенные изменения в исходный код. Рассмотрим команды предназначенные для решения этой задачи.

Начнем с 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

Команда 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

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

Название 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 - скрипты

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 :

 

Библиография

Дополнительное чтение :  

Страница отзывов

У каждой заметки есть страница отзывов. На этой странице вы можете оставить свой комментарий или просмотреть комментарии других читателей.
 talkback page 

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:
es -> -- Manuel Muriel Cordero
en -> ru Kirill Poukhliakov

2000-11-03, generated by lfparser version 1.9