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

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

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

#

# Этот модифицированный вариант включен в документ на основе

#+ документа "LICENSE" из пакета "Crack"

#+ с которым распространяется оригинальный сценарий.


# Этот скрипт обрабатывает текстовые файлы и создает отсортированный список

#+ слов, найденных в этих файлах.

# Он может оказаться полезным для сборки словарей

#+ и проведения лексикографического анализа.


E_BADARGS=65


if [ ! -r "$1" ] # Необходим хотя бы один аргумент --

then #+ имя файла.

echo "Порядок использования: $0 имена_файлов"

exit $E_BADARGS

fi


# SORT="sort" # Необходимость задания ключей сортировки отпала.

#+ Изменено, по отношению к оригинальному сценарию.


cat $* | # Выдать содержимое файлов на stdout.

tr A-Z a-z | # Преобразовать в нижний регистр.

tr ' ' '12' | # Новое: заменить пробелы символами перевода строки.

# tr -cd '12[a-z][0-9]' | # В оригинальном сценарии: удалить все символы,

#+ которые не являются буквами или цифрами.

tr -c '12a-z' '12' | # Вместо удаления

#+ неалфавитно-цифровые символы заменяются на перевод строки.

sort |

uniq | # Удалить повторяющиеся слова.

grep -v '^#' | # Удалить строки, начинающиеся с "#".

grep -v '^$' # Удалить пустые строки.


exit 0

Пример A-10. Расчет индекса "созвучности"

#!/bin/bash

# soundex.sh: Расчет индекса "созвучности"


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

# Сценарий Soundex

# Автор

# Mendel Cooper

# [email protected]

# 23 Января 2002 г.

#

# Условия распространения: Public Domain.

#

# Несколько отличающаяся версия этого сценария была опубликована

#+ Эдом Шэфером (Ed Schaefer) в Июле 2002 года в колонке "Shell Corner"

#+ "Unix Review" on-line,

#+ http://www.unixreview.com/documents/uni1026336632258/

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


ARGCOUNT=1 # Требуется аргумент командной строки.

E_WRONGARGS=70


if [ $# -ne "$ARGCOUNT" ]

then

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

exit $E_WRONGARGS

fi


assign_value () # Присвоить числовые значения

{ #+ символам в имени.


val1=bfpv # 'b,f,p,v' = 1

val2=cgjkqsxz # 'c,g,j,k,q,s,x,z' = 2

val3=dt # и т.п.

val4=l

val5=mn

val6=r


# Попробуйте разобраться в том, что здесь происходит.


value=$( echo "$1"

| tr -d wh

| tr $val1 1 | tr $val2 2 | tr $val3 3

| tr $val4 4 | tr $val5 5 | tr $val6 6

| tr -s 123456

| tr -d aeiouy )


# Символам в имени присваиваются числовые значения.

# Удаляются повторяющиеся числа, если они не разделены гласными.

# Гласные игнорируются, если они не являются разделителями, которые удаляются в последнюю очередь.

# Символы 'w' и 'h' удаляются в первую очередь.

}


input_name="$1"

echo

echo "Имя = $input_name"


# Перевести все символы в имени в нижний регистр.

# ------------------------------------------------

name=$( echo $input_name | tr A-Z a-z )

# ------------------------------------------------


# Начальный символ в индекса "созвучия": первая буква в имени.

# --------------------------------------------


char_pos=0 # Начальная позиция в имени.

prefix0=${name:$char_pos:1}

prefix=`echo $prefix0 | tr a-z A-Z`

# Первую букву в имени -- в верхний регистр.


let "char_pos += 1" # Передвинуть "указатель" на один символ.

name1=${name:$char_pos}


# ++++++++++++++++++++++++++++ Исключение отдельных ситуаций +++++++++++++++++++++++++++++++

# Теперь мы передвинулись на один символ вправо.

# Если второй символ в имени совпадает с первым

#+ то его нужно отбросить.

# Кроме того, мы должны проверить -- не является ли первый символ

#+ гласной, 'w' или 'h'.


char1=`echo $prefix | tr A-Z a-z` # Первый символ -- в нижний регистр.


assign_value $name

s1=$value

assign_value $name1

s2=$value

assign_value $char1

s3=$value

s3=9$s3 # Если первый символ в имени -- гласная буква

#+ или 'w' или 'h',

#+ то ее "значение" нужно отбросить.

#+ Поэтому ставим 9, или другое

#+ неиспользуемое значение, которое можно будет проверить.


if [[ "$s1" -ne "$s2" || "$s3" -eq 9 ]]

then

suffix=$s2

else

suffix=${s2:$char_pos}

fi

# ++++++++++++++++++++++++ Конец исключения отдельных ситуаций +++++++++++++++++++++++++++++++


padding=000 # Дополнить тремя нулями.


soun=$prefix$suffix$padding # Нули добавить в конец получившегося индекса.


MAXLEN=4 # Ограничить длину индекса 4-мя символами.

soundex=${soun:0:$MAXLEN}


echo "Индекс созвучия = $soundex"


echo


# Индекс "созвучия" - это метод индексации и классификации имен

#+ по подобию звучания.

# Индекс "созвучия" начинается с первого символа в имени,

#+ за которым следуют 3-значный расчетный код.

# Имена, которые произносятся примерно одинаково, имеют близкие индексы "созвучия".


# Например:

# Smith и Smythe -- оба имеют индекс "созвучия" "S530".

# Harrison = H625

# Hargison = H622

# Harriman = H655


# Как правило эта методика дает неплохой результат, но имеются и аномалии.

#

#

# Дополнительную информацию вы найдете на

#+ "National Archives and Records Administration home page",

#+ http://www.nara.gov/genealogy/soundex/soundex.html


# Упражнение:

# ----------

# Упростите блок "Исключение отдельных ситуаций" .


exit 0

Пример A-11. "Игра "Жизнь""

#!/bin/bash

# life.sh: Игра "Жизнь"


# ##################################################################### #

# Это Bash-версия известной игры Джона Конвея (John Conway) "Жизнь". #

# --------------------------------------------------------------------- #

# Прямоугольное игровое поле разбито на ячейки, в каждой ячейке может #

#+ располагаться живая особь. #

# Соответственно, ячейка с живой особью отмечается точкой, #

#+ не занятая ячейка -- остается пустой. #

# Изначально, ячейки заполняются из файла -- #

#+ это первое поколение, или "поколение 0" #

# Воспроизводство особей, в каждом последующем поколении, #

#+ определяется следующими правилами #

# 1) Каждая ячейка имеет "соседей" #

#+ слева, справа, сверху, снизу и 4 по диагоналям. #

# 123 #

# 4*5 #

# 678 #

# #

# 2) Если живая особь имеет 2 или 3 живых соседей, то она остается жить.#

# 3) Если пустая ячейка имеет 3 живых соседей -- #

#+ в ней "рождается" новая особь #

SURVIVE=2 #

BIRTH=3 #

# 4) В любом другом случае, живая особь "погибает" #

# ##################################################################### #


startfile=gen0 # Начальное поколение из файла по-умолчанию -- "gen0".

# если не задан другой файл, из командной строки.

#

if [ -n "$1" ] # Проверить аргумент командной строки -- файл с "поколениемn 0".

then

if [ -e "$1" ] # Проверка наличия файла.

then

startfile="$1"

fi

fi


ALIVE1=.

DEAD1=_

# Представление "живых" особей и пустых ячеек в файле с "поколением 0".


# Этот сценарий работает с игровым полем 10 x 10 grid (может быть увеличено,

#+ но большое игровое поле будет обрабатываться очень медленно).

ROWS=10

COLS=10


GENERATIONS=10 # Максимальное число поколений.


NONE_ALIVE=80 # Код завершения на случай,

#+ если не осталось ни одной "живой" особи.

TRUE=0

FALSE=1

ALIVE=0

DEAD=1


avar= # Текущее поколение.

generation=0 # Инициализация счетчика поколений.


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


let "cells = $ROWS * $COLS"

# Количество ячеек на игровом поле.


declare -a initial # Массивы ячеек.

declare -a current


display ()

{


alive=0 # Количество "живых" особей.

# Изначально -- ноль.


declare -a arr

arr=( `echo "$1"` ) # Преобразовать аргумент в массив.


element_count=${#arr[*]}


local i

local rowcheck


for ((i=0; i<$element_count; i++))

do


# Символ перевода строки -- в конец каждой строки.

let "rowcheck = $i % ROWS"

if [ "$rowcheck" -eq 0 ]

then

echo # Перевод строки.

echo -n " " # Выравнивание.

fi


cell=${arr[i]}


if [ "$cell" = . ]

then

let "alive += 1"

fi


echo -n "$cell" | sed -e 's/_/ /g'

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

done


return


}


IsValid () # Проверка корректности координат ячейки.

{


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

then

return $FALSE

fi


local row

local lower_limit=0 # Запрет на отрицательные координаты.

local upper_limit

local left

local right


let "upper_limit = $ROWS * $COLS - 1" # Номер последней ячейки на игровом поле.

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