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

Пример 34-1. Расширение строк

Пример 34-1. Расширение строк

#!/bin/bash

# "Расширение" строк (String expansion).

# Введено в Bash, начиная с версии 2.

# Строки вида $'xxx'

# могут содержать дополнительные экранированные символы.

echo $'Звонок звенит 3 раза a a a'

echo $'Три перевода формата f f f'

echo $'10 новых строк nnnnnnnnnn'

exit 0

Пример 34-2. Косвенные ссылки на переменные -- новый метод

#!/bin/bash

# Косвенные ссылки на переменные.

a=letter_of_alphabet

letter_of_alphabet=z

echo "a = $a" # Прямая ссылка.

echo "Now a = ${!a}" # Косвенная ссылка.

# Форма записи ${!variable} намного удобнее старой "eval var1=$$var2"

echo

t=table_cell_3

table_cell_3=24

echo "t = ${!t}" # t = 24

table_cell_3=387

echo "Значение переменной t изменилось на ${!t}" # 387

# Теперь их можно использовать для ссылок на элементы массива,

# или для эмуляции многомерных массивов.

# Было бы здорово, если бы косвенные ссылки допускали индексацию.

exit 0

Пример 34-3. Простая база данных, с применением косвенных ссылок

#!/bin/bash

# resistor-inventory.sh

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

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

# Данные

B1723_value=470 # сопротивление (Ом)

B1723_powerdissip=.25 # рассеиваемая мощность (Вт)

B1723_colorcode="желтый-фиолетовый-коричневый" # цветовая маркировка

B1723_loc=173 # где

B1723_inventory=78 # количество (шт)

B1724_value=1000

B1724_powerdissip=.25

B1724_colorcode="коричневый-черный-красный"

B1724_loc=24N

B1724_inventory=243

B1725_value=10000

B1725_powerdissip=.25

B1725_colorcode="коричневый-черный-оранжевый"

B1725_loc=24N

B1725_inventory=89

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

echo

PS3='Введите ноиер: '

echo

select catalog_number in "B1723" "B1724" "B1725"

do

Inv=${catalog_number}_inventory

Val=${catalog_number}_value

Pdissip=${catalog_number}_powerdissip

Loc=${catalog_number}_loc

Ccode=${catalog_number}_colorcode

echo

echo "Номер по каталогу $catalog_number:"

echo "Имеется в наличии ${!Inv} шт. [${!Val} Ом / ${!Pdissip} Вт]."

echo "Находятся в лотке # ${!Loc}."

echo "Цветовая маркировка: "${!Ccode}"."

break

done

echo; echo

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

# ----------

# Переделайте этот сценарий так, чтобы он использовал массивы вместо косвенных ссылок.

# Какой из вариантов более простой и интуитивный?

# Примечание:

# ----------

# Язык командной оболочки не очень удобен для написания приложений,

#+ работающих с базами данных.

# Для этой цели лучше использовать языки программирования, имеющие

#+ развитые средства для работы со структурами данных,

#+ такие как C++ или Java (может быть Perl).

exit 0

Пример 34-4. Массивы и другие хитрости для раздачи колоды карт в четыре руки

#!/bin/bash

# На старых системах может потребоваться вставить #!/bin/bash2.

# Карты:

# раздача в четыре руки.

UNPICKED=0

PICKED=1

DUPE_CARD=99

LOWER_LIMIT=0

UPPER_LIMIT=51

CARDS_IN_SUIT=13

CARDS=52

declare -a Deck

declare -a Suits

declare -a Cards

# Проще и понятнее было бы, имей мы дело

# с одним 3-мерным массивом.

# Будем надеяться, что в будущем, поддержка многомерных массивов будет введена в Bash.

initialize_Deck ()

{

i=$LOWER_LIMIT

until [ "$i" -gt $UPPER_LIMIT ]

do

Deck[i]=$UNPICKED # Пометить все карты в колоде "Deck", как "невыданная".

let "i += 1"

done

echo

}

initialize_Suits ()

{

Suits[0]=Т # Трефы

Suits[1]=Б # Бубны

Suits[2]=Ч # Червы

Suits[3]=П # Пики

}

initialize_Cards ()

{

Cards=(2 3 4 5 6 7 8 9 10 В Д K Т)

# Альтернативный способ инициализации массива.

}

pick_a_card ()

{

card_number=$RANDOM

let "card_number %= $CARDS"

if [ "${Deck[card_number]}" -eq $UNPICKED ]

then

Deck[card_number]=$PICKED

return $card_number

else

return $DUPE_CARD

fi

}

parse_card ()

{

number=$1

let "suit_number = number / CARDS_IN_SUIT"

suit=${Suits[suit_number]}

echo -n "$suit-"

let "card_no = number % CARDS_IN_SUIT"

Card=${Cards[card_no]}

printf %-4s $Card

# Вывод по столбцам.

}

seed_random () # Переустановка генератора случайных чисел.

{

seed=`eval date +%s`

let "seed %= 32766"

RANDOM=$seed

}

deal_cards ()

{

echo

cards_picked=0

while [ "$cards_picked" -le $UPPER_LIMIT ]

do

pick_a_card

t=$?

if [ "$t" -ne $DUPE_CARD ]

then

parse_card $t

u=$cards_picked+1

# Возврат к индексации с 1 (временно).

let "u %= $CARDS_IN_SUIT"

if [ "$u" -eq 0 ] # вложенный if/then.

then

echo

echo

fi

# Смена руки.

let "cards_picked += 1"

fi

done

echo

return 0

}

# Структурное программирование:

# вся логика приложения построена на вызове функций.

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

seed_random

initialize_Deck

initialize_Suits

initialize_Cards

deal_cards

exit 0

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

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

# Добавьте комментарии, чтобы до конца задокументировать этот сценарий.

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

# Исправьте сценарий так, чтобы карты в каждой руке выводились отсортированными по масти.

# Вы можете добавить и другие улучшения.

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

# Упростите логику сценария.

Оглавление книги


Генерация: 0.080. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз