<Ctrl+D>
Разделителем полей является символ ‘#’.
2. Создайте файл scen_1.awk. Расширение awk является общепринятым соглашением относительно именования файлов сценариев awk. Вот текст этого файла:
#!./awk -f
# Имя файла: scen_1.awk
# Все строки комментариев должны начинаться с символа ‘#’
# Командная строка: scen_1.awk popular.txt
# Вычисление суммарного количества уникальных скачиваний за неделю
# Сначала выводим заголовок
BEGIN {
FS=“#”
print “\nName program copy\n-------------------------”}
{printf “%-20s %d\n”, $1, $7}
# Суммируем количество уникальных скачиваний за неделю
{tot+=$7}
# В завершение выводим суммарное скачивание за неделю
END {print “\nsumma copy: ” tot}
Ключевым моментом сценария является первая строка, выглядящая каккомментарий:
#!./awk -f
На самом деле это своеобразная системная инструкция, указывающая, какая программа должна выполнять данный сценарий. Подобная инструкция должна быть первой строкой любого сценария. Общий ее формат таков:
#! /путь/программа [командная_строка]
Выражение #! называется “магической” последовательностью. Подразумевается, что, во-первых, система, в которой запускается сценарий, распознает эту последовательность, а, во-вторых, указанная программа воспринимает символ ‘#’ как признак комментария.
Когда происходит запуск исполняемого файла, система проверяет, начинается ли он с “магической” последовательности. Если нет, значит, файл содержит машинные коды и выполняется непосредственно. Если же обнаружено выражение #!, то это файл сценария. В таком случае происходит следующее:
1. Первая строка сценария заменяет собой командную строку, из нее удаляется “магическая” последовательность;
2. Предыдущая командная строка передается новой командной строке в качестве аргумента.
В нашем случае это означает, что при запуске сценария вместо команды:
$ scen_1.awk popular.txt
в действительности выполняется такая команда:
$./awk -f scen_1.awk popular.txt
Опция -f утилиты awk говорит о том, что выполняемые команды находятся в указанном вслед за ней файле.
3. После создания файл s cen_1.awk необходимо сделать исполняемым с помощью команды
$./chmod u+x scen_1.awk
1. С помощью следующих команд можно проверить стал ли файл s cen_1.awk выполняемым:
$ [ -x scen_1.awk ]
$./echo $?
Первая из этих команд проверяет, является ли файл выполняемым. Пробелы после открывающей скобки и перед закрывающей скобкой обязательны. Вторая возвращает код завершения первой команды. Возвращаемое нулевое значение свидетельствует о том, что условие выполняется, любое другое значение говорит о наличии ошибки.
2. Выполните сценарий:
$./scen_1.awk popular.txt
Обратите внимание на то, что разделитель полей задан с помощью встроенной переменной FS. В сценарии используется команда printf (форматного вывода). При выводе строковые данные выровнены по левому краю — ширина поля 20 символов, во втором поле выводятся целые числа.
Выражение tot+=$7 заключено в фигурные скобки. Попробуйте убрать в сценарии фигурные скобки.
1. Следующий сценарий s cen_2.awk выводит информацию о программах имеющих количество уникальных скачиваний за 30 дней больше заданного в командной строке:
#!./awk -f
# Имя файла: scen_2.awk
# Командная строка: scen_2.awk KOL=n popular.txt
# Вывод информации о программах имеющих количество уникальных
# считываний за 30 дней больше заданного
BEGIN {FS=“#”}
{if($6 > KOL) print $0}
1. Сделайте сценарий выполняемым и выполните его с параметром равным 500.
$./chmod u+x scen_2.awk
$./scen_2.awk KOL=500 popular.txt
Способы присваивания значений shell-переменным
Имя shell-переменной – это начинающаяся с буквы последовательность букв, цифр и подчеркиваний. Значение shell-переменной – всегда строка символов!
Из предыдущих лабораторных работ известен способ присвоить значение переменной с помощью команды "read" в диалоговом режиме. Обычно команде "read" в командном файле предшествует команда "echo", которая позволяет предварительно выдать какое-то сообщение на экран. Например:
echo -n "Введите трехзначное число:"
Read x
При выполнении этого фрагмента командного файла, после вывода на экран сообщения
Введите трехзначное число:
интерпретатор остановится, и будет ждать ввода значения с клавиатуры. Если вы ввели, скажем, "753" то это и станет значением переменной "x".
Одна команда "read" может прочитать (присвоить) значения сразу для нескольких переменных. Если переменных в "read" больше, чем их введено (через пробелы), оставшимся присваивается пустая строка. Если передаваемых значений больше, чем переменных в команде "read", то лишние игнорируются.
Существуют также и другие способы присваивания значений переменным.
1. Для присваивания значений переменным может использоваться оператор присваивания "=".
var_1=13 - "13" - это не число, а строка из двух цифр.
var_2="ОС UNIX" - здесь двойные кавычки (" ") необходимы, так как в строке есть пробел.
Обратим внимание на то, что, как переменная, так и ее значение должны быть записаны без пробелов относительно символа "=". Кстати, как видно из примеров, первым словом в командной строке может стоять не только имя команды, но и присваивание значения переменной. Об этом как раз и говорит наличие в беспробельной строке символов наличие (незаэкранированного) символа "=".
1. Запись
DAT=`date`
приводит к тому, что сначала выполняется команда "date" (обратные кавычки говорят о том, что сначала должна быть выполнена заключенная в них команда), а результат ее выполнения, вместо выдачи на стандартный выход, приписывается в качестве значения переменной, в данном случае "DAT".
При обращении к shell-переменной необходимо перед именем ставить символ "$". Так команды
echo $var_2
echo "var_2 = $var_2"
выдадут на экран
ОС UNIX
var_2 = ОС UNIX
То, что здесь присутствуют пробелы между именем переменной и символом присваивания, а также между символом присваивания и значением, так это потому, что здесь мы имеем дело лишь с текстом, куда подставлены значения переменных. Там, где действительно выполняется присваивание, пробелы в этих местах НЕДОПУСТИМЫ. Присваивание, скажем, w= означает присваивание переменной "w" пустой строки. Но и пустую строку лучше присваивать аккуратно, например w="".
Для того, чтобы имя переменной не сливалось со строкой, следующей за именем переменной, используются фигурные скобки.
Пусть a=c:/temp/bin/
тогда
/cat c:/temp/bin/protocol.txt
и
/cat ${a}protocol.txt
равноценны (т.е. "cat" выдаст на экран содержимое одного и того же файла).
Практическая (лабораторная) работа:
1.Создайте в текущем каталоге файл protocol.txt, занесите в него строку
Протокол выполнения Л.Р №6
2. Задайте значения переменным var_1=13, var_2, DAT, a.
3. Выведите значения этих переменных в файл protocol.txt.
Экранирование
Рассмотрим более подробно приемы экранирования, используемые в shell. В качестве средств экранирования используются двойные кавычки (" "), одинарные кавычки (' ') и бэк-слэш (\).
Из примеров очевидно их действие (в одной строке можно записывать несколько приcваиваний):
x=22 y=33 z=$x
A="$x" B='$x' C=\$x
D="$x + $y + $z" E='$x + $y + $z' F=$x\ +\ $y\ +\ $z
Тогда
echo A = $A B = $B C = $C
echo D = $D E = $E F = $F
eval echo evaluated A = $A
eval echo evaluated B = $B
eval echo evaluated C = $C
Выдадут на экран
A = 22 B = $x C = $x
D = 22 + 33 + 22 E = $x + $y + $z F = 22 + 33 + 22
evaluated A = 22
evaluated B = 22
evaluated C = 22
В трех последних случаях использована команда "eval" (от evaluate - означивать), которая в подставленной в нее (в качестве аргумента) команде выполняет означивание переменных (если таковые имеются). В результате значение "A" остается прежним, поскольку "A" имеет значение "22". А переменные "B" и "C" имеют значение "$x". За счет означивания, которое было выполнено командой "eval" - evaluated "B" и "C" дают значения "22".
Еще один пример на "eval". Пусть
w=\$v v=\$u u=5
В результате выполнения команд
echo $w
eval echo $w
eval eval echo $w
на экран будет выведено
$v
$u
Приведем еще примеры, связанные с экранированием перевода строки. Пусть переменной "string" присвоено значение "массива" 2x3:
Abc
Def
Обратим внимание, что для избежания присваивания лишних пробелов вторая строка массива начата с первой позиции следующей строки:
string="abc
def"
Тогда три варианта записи переменной в команде "echo"
echo $string
echo '$string'
echo "$string"
дадут соответственно три различных результата:
Abc def
$string
Abc
Def
Заметим также, что бэк-слэш (\) не только экранирует следующий за ним символ, что позволяет использовать специальные символы просто как символы, представляющие сами себя (он может экранировать и сам себя - \\), но в командном файле бэк-слэш позволяет об'единять строки в одну (экранировать конец строки).
Например, командная строка:
cat f1 | grep -h result | sort | cat -b > f2
может быть записан в командном файле, следующим образом
cat f1 | grep -h \
result | sort | cat -b > f2