KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Мендель Купер - Искусство программирования на языке сценариев командной оболочки

Мендель Купер - Искусство программирования на языке сценариев командной оболочки

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Мендель Купер, "Искусство программирования на языке сценариев командной оболочки" бесплатно, без регистрации.
Перейти на страницу:

# Ключ '-c' в команде "head" выводит заданное

#+ количество символов, а не строк.

then

echo "Файл "$file" -- сценарий."

else

echo "Файл "$file" не является сценарием."

fi

done

exit 0

Пример 12-10. Генератор 10-значных случайных чисел

#!/bin/bash

# rnd.sh: Генератор 10-значных случайных чисел


# Автор: Stephane Chazelas.


head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p'


# =================================================================== #


# Описание

# --------


# head:

# -c4 -- первые 4 байта.


# od:

# -N4 ограничивает вывод 4-мя байтами.

# -tu4 беззнаковый десятичный формат вывода.


# sed:

# -n, в комбинации с флагом "p", в команде "s",

# выводит только совпадающие с шаблоном строки.


# Автор сценария описывает действия 'sed' таким образом:


# head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p'

# ----------------------------------> |


# Передает вывод в "sed" --------> |

# пусть это будет 0000000 1198195154n


# sed начинает читать символы: 0000000 1198195154n.

# Здесь он находит символ перевода строки,

# таким образом он получает строку (0000000 1198195154).

# Затем он просматривает <диапазон><действие>. Первый и единственный -- это


# диапазон действие

# 1 s/.* //p


# Номер строки попадает в заданный лиапазон, так что теперь он приступает к выполнению действия:

# пытается заменить наибольшую подстроку, заканчивающуюся пробелом

# ("0000000 ") "ничем" (//), и если замена произведена -- выводит результат

# ("p" -- это флаг команды "s", а не команда "p", которая имеет иное значение).


# теперь sed готов продолжить чтение входного потока. (Обратите внимание:

# если опустить ключ -n, то sed выведет строку еще раз)


# Теперь sed дочитывает остаток строки.

# Он готов приступить к анализу 2-й строки (которая отмечена '$'

# как последняя).

# Поскольку строка не попадает в заданный <диапазон>, на этом обработка прекращается.


# Проще говоря, команда sed означает:

# "В первой строке удалить любые символы, вплоть до последнего встреченного пробела,

# и затем вывести остаток."


# Сделать это можно более простым способом:

# sed -e 's/.* //;q'


# Где, заданы два <диапазона><действия> (можно записать и по другому

# sed -e 's/.* //' -e q):


# диапазон действие

# ничего (для совпадающих строк) s/.* //

# ничего (для совпадающих строк) q (quit)


# Здесь sed считывает только первую строку.

# Выполняет оба действия, и выводит строку перед завершением

# (действие "q"), поскольку ключ "-n" опущен.


# =================================================================== #


# Простая альтернатива:

# head -c4 /dev/urandom| od -An -tu4


exit 0

См. также Пример 12-30.

tail

Выводит последние строки из файла на stdout (по-умолчанию -- 10 строк). Обычно используется для мониторинга системных журналов. Ключ -f, позволяет вести непрерывное наблюдение за добавляемыми строками в файл.

Пример 12-11. Мониторинг системного журнала с помощью tail

#!/bin/bash


filename=sys.log


cat /dev/null > $filename; echo "Создание / очистка временного файла."

# Если файл отсутствует, то он создается,

#+ и очищается, если существует.

# : > filename и > filename дают тот же эффект.


tail /var/log/messages > $filename

# Файл /var/log/messages должен быть доступен для чтения.


echo "В файл $filename записаны последние строки из /var/log/messages."


exit 0

См. также Пример 12-4, Пример 12-30 и Пример 29-6.

grep

Многоцелевая поисковая утилита, использующая регулярные выражения. Изначально это была команда в древнем строчном редакторе ed, g/re/p, что означает -- global - regular expression - print.

grep pattern [file...]

Поиск участков текста в файле(ах), соответствующих шаблону pattern, где pattern может быть как обычной строкой, так и регулярным выражением.

bash$ grep '[rst]ystem.$' osinfo.txt

The GPL governs the distribution of the Linux operating system.


Если файл(ы) для поиска не задан, то команда grep работает как фильтр для устройства stdout, например в конвейере.

bash$ ps ax | grep clock

765 tty1 S 0:00 xclock

901 pts/1 S 0:00 grep clock


-i -- выполняется поиск без учета регистра символов.

-w -- поиск совпадений целого слова.

-l -- вывод только имен файлов, в которых найдены участки, совпадающие с заданным образцом/шаблоном, без вывода совпадающих строк.

-r -- (рекурсивный поиск) поиск выполняется в текущем каталоге и всех вложенных подкаталогах.

The -n option lists the matching lines, together with line numbers.

bash$ grep -n Linux osinfo.txt

2:This is a file containing information about Linux.

6:The GPL governs the distribution of the Linux operating system.


-v (или --invert-match) -- выводит только строки, не содержащие совпадений.

grep pattern1 *.txt | grep -v pattern2


# Выводятся строки из "*.txt", совпадающие с "pattern1",

# но ***не*** совпадающие с "pattern2".


-c (--count) -- выводит количество совпадений без вывода самих совпадений.

grep -c txt *.sgml # (количество совпадений с "txt" в "*.sgml" файлах)


# grep -cz .

# ^ точка

# означает подсчет (-c) непустых ("." -- содержащих хотя бы один символ) элементов,

# разделенных нулевыми байтами (-z)

#

printf 'a bnc dnnnnn00n00e0000nf' | grep -cz . # 4

printf 'a bnc dnnnnn00n00e0000nf' | grep -cz '$' # 5

printf 'a bnc dnnnnn00n00e0000nf' | grep -cz '^' # 5

#

printf 'a bnc dnnnnn00n00e0000nf' | grep -c '$' # 9

# По-умолчанию, в качестве разделителя, принимается символ перевода строки (n).


# Обратите внимание: ключ -z характерен для GNU-версии "grep".


# Спасибо S.C.


Если grep вызывается для поиска по группе файлов, то вывод будет содержать указание на имена файлов, в которых найдены совпадения.

bash$ grep Linux osinfo.txt misc.txt

osinfo.txt:This is a file containing information about Linux.

osinfo.txt:The GPL governs the distribution of the Linux operating system.

misc.txt:The Linux operating system is steadily gaining in popularity.


Для того, чтобы заставить grep выводить имя файла, когда поиск производится по одному-единственному файлу, достаточно указать устройство /dev/null в качестве второго файла.

bash$ grep Linux osinfo.txt /dev/null

osinfo.txt:This is a file containing information about Linux.

osinfo.txt:The GPL governs the distribution of the Linux operating system.


Если совпадение было найдено, то grep возвращает код завершения -- 0, это может оказаться полезным при выполнении поиска в условных операторах ( в таких случаях особый интерес может представлять ключ -q, который подавляет вывод).

SUCCESS=0 # если найдено совпадение

word=Linux

filename=data.file


grep -q "$word" "$filename" # "-q" -- подавляет вывод на stdout.


if [ $? -eq $SUCCESS ]

then

echo "Образец $word найден в $filename"

else

echo "Образец $word в файле $filename не найден"

fi


Пример 29-6 -- пример поиска заданного образца в системном журнале, с помощью grep.

Пример 12-12. Сценарий-эмулятор "grep"

#!/bin/bash

# grp.sh: Очень "грубая" реализация 'grep'.


E_BADARGS=65


if [ -z "$1" ] # Проверка наличия аргументов.

then

echo "Порядок использования: `basename $0` pattern"

exit $E_BADARGS

fi


echo


for file in * # Обход всех файлов в $PWD.

do

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*