Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Название:Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание
- Автор:
- Жанр:
- Издательство:Питер
- Год:2017
- Город:СПб.
- ISBN:978-5-496-03029-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дейв Тейлор - Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание краткое содержание
Цель этой книги — продемонстрировать практические приемы программирования сценариев на bash и познакомить с самыми распространенными утилитами на коротких и компактных примерах, не вдаваясь в излишние подробности. Экспериментируйте с этими сценариями — ломайте, исправляйте и приспосабливайте их под свои нужды, чтобы понять, как они работают. Только так вы сможете решать самые сложные задачи.
Сценарии командной оболочки. Linux, OS X и Unix. 2-е издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
tr '[a-zA-Z]' '[n-za-mN-ZA-M]'
Например:
$ echo "So two people walk into a bar…" | tr '[a-zA-Z]' '[n-za-mN-ZA-M]'
Fb gjb crbcyr jnyx vagb n one…
Чтобы вернуть строке читаемый вид, достаточно применить то же преобразование:
$ echo 'Fb gjb crbcyr jnyx vagb n one…' | tr '[a-zA-Z]' '[n-za-mN-ZA-M]'
So two people walk into a bar…
Известно, что этот подстановочный шифр использовался в фильме «2001: A Space Odyssey» [7] В отечественном кинопрокате вышел под названием «Космическая одиссея 2001 года». — Примеч. пер.
. Помните, как там назывался компьютер? Проверим его:
$ echo HAL | tr '[a-zA-Z]' '[b-zaB-ZA]'
IBM
Другой короткий пример — проверка палиндромов. Введите что-нибудь, что на ваш взгляд является палиндромом, и этот код проверит его:
testit="$(echo $@ | sed 's/[^[: alpha: ]]//g' | tr '[: upper: ]' '[: lower: ]')"
backward="$(echo $testit | rev)"
if ["$testit" = "$backward"]; then
··echo "$@ is a palindrome"
else
··echo "$@ is not a palindrome"
fi
Палиндромом называется слово, которое одинаково читается слева направо и справа налево, поэтому первым делом код удаляет все неалфавитные символы и преобразует все буквы в нижний регистр. Затем Unix-утилита rev переворачивает задом наперед строку, полученную ею из стандартного ввода. Если прямая и перевернутая версии совпадают, значит, проверяемая строка является палиндромом; если они различаются, это не палиндром.
Показанные далее игры немногим сложнее, но все они достаточно забавны, чтобы вы добавили их в свою систему.
№ 83. Декодирование: игра в слова
Это простейшая игра в анаграммы. Если вы когда-нибудь сталкивались с подобными играми, то легко поймете суть: выбирается случайное слово, и буквы в нем переставляются случайным образом. Задача игрока — угадать исходное слово за как можно меньшее число попыток. Полный сценарий, реализующий эту игру, приводится в листинге 12.1, но, чтобы получить список слов, вам также нужно загрузить файл long-words.txt из ресурсов книги http://www.nostarch.com/wcss2/и сохранить его в каталоге /usr/lib/games .
Код
Листинг 12.1.Игровой сценарий unscramble
··#!/bin/bash
··# unscramble — выбирает слово, кодирует его, переставляя буквы,
··#·· и предлагает пользователю угадать исходное слово (или фразу).
··wordlib="/usr/lib/games/long-words.txt"
··scrambleword()
··{
····# Выбирает случайное слово из wordlib и кодирует его.
····# Исходное слово сохраняется в $match, закодированное — в $scrambled.
····match="$(
randomquote $wordlib)"
····echo "Picked out a word!"
····len=${#match}
····scrambled=""; lastval=1
····for ((val=1; $val < $len;))
····do
······if [$(($RANDOM % 2)) −eq 1]; then
········scrambled=$scrambled$(echo $match | cut −c$val)
······else
········scrambled=$(echo $match | cut −c$val)$scrambled
······fi
······val=$(($val + 1))
····done
··}
··if [! -r $wordlib]; then
····echo "$0: Missing word library $wordlib" >&2
····echo "(online: http://www.intuitive.com/wicked/examples/long-words.txt" >&2
····echo "save the file as $wordlib and you're ready to play!)" >&2
····exit 1
··fi
··newgame=""; guesses=0; correct=0; total=0
··until ["$guess" = "quit"]; do
····scrambleword
····echo ""
····echo "You need to unscramble: $scrambled"
····guess="??"; guesses=0
····total=$(($total + 1))
····while ["$guess"!= "$match" −a "$guess"!= "quit" −a "$guess"!= "next"]
····do
······echo ""
······/bin/echo −n "Your guess (quit|next): "
······read guess
······if ["$guess" = "$match"]; then
········guesses=$(($guesses + 1))
········echo ""
········echo "*** You got it with tries = ${guesses}! Well done!! ***"
········echo ""
········correct=$(($correct + 1))
······elif ["$guess" = "next" −o "$guess" = "quit"]; then
········echo "The unscrambled word was \"$match\". Your tries: $guesses"
······else
········echo "Nope. That's not the unscrambled word. Try again."
········guesses=$(($guesses + 1))
······fi
····done
··done
··echo "Done. You correctly figured out $correct out of $total scrambled words."
··exit 0
Как это работает
Для выбора случайной строки из файла используется randomquote (сценарий № 68 из главы 8) , несмотря на то что первоначально этот сценарий был написан для работы с веб-страницами (многие хорошие утилиты Unix оказываются полезными в контекстах, отличных от тех, для которых они создавались).
Сложнее всего было реализовать кодирование слова. В Unix нет удобных утилит для этого, но, оказывается, слово можно закодировать непредсказуемым способом, если выполнить последовательный перебор букв в нем и случайно добавлять каждую следующую букву в начало или в конец закодированной последовательности .
Обратите внимание на местоположение $scrambled в двух строках: в первой следующая буква добавляется в конец $scrambled, а во второй — в начало.
В остальном логика игры должна быть понятна: внешний цикл until выполняется, пока пользователь не введет слово quit в качестве ответа, а внутренний цикл while
выполняется, пока пользователь не угадает слово или не введет next, чтобы перейти к следующему слову.
Запуск сценария
Этот сценарий не имеет аргументов, так что просто введите его имя в командной строке и начните игру!
Результаты
После запуска сценарий выводит закодированные слова разной длины и подсчитывает количество слов, угаданных пользователем, как показано в листинге 12.2.
Листинг 12.2.Запуск игрового сценария unscramble
$ unscramble
Picked out a word!
You need to unscramble: ninrenoccg
Your guess (quit|next): concerning
*** You got it with tries = 1! Well done!! ***
Picked out a word!
You need to unscramble: esivrmipod
Your guess (quit|next): quit
The unscrambled word was "improvised". Your tries: 0
Done. You correctly figured out 1 out of 2 scrambled words.
Первая же попытка оказалась успешной, и это вдохновляет!
Усовершенствование сценария
Вывод подсказки, хоть в каком-нибудь виде, сделал бы игру более интересной, также пригодился бы флаг, позволяющий ограничивать минимальную длину слова. В первом случае можно было бы за определенные штрафные очки показывать первые n букв из исходного слова и в ответ на каждый запрос подсказки добавлять еще одну букву. Для второго случая необходимо расширить словарь, так как предлагаемый вместе со сценарием содержит слова не короче 10 букв — хитро!
№ 84. Виселица: угадай слово, пока не поздно
Интервал:
Закладка: