Мендель Купер - Искусство программирования на языке сценариев командной оболочки
- Название:Искусство программирования на языке сценариев командной оболочки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Мендель Купер - Искусство программирования на языке сценариев командной оболочки краткое содержание
Данное руководство не предполагает наличие у читателя познаний в области программирования на языке сценариев, однако, быстро восполняет этот недостаток, постепенно, шаг за шагом раскрывая мудрость и красоту UNIX. Это руководство может рассматриваться как учебник, предназначенный для самостоятельного изучения или как справочник по программированию на shell. Руководство снабжено серией хорошо прокомментированных примеров, поскольку лучший путь к изучению языка сценариев -- это написание сценариев.
Искусство программирования на языке сценариев командной оболочки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
#+ элемент массива "исчезает".
# Вопрос: это относится к строкам в "строгих" или "мягких" кавычках?
zap='новый*'
declare -a array9=( ${array0[@]/$zap/} )
echo
echo "Элементы массива array9: ${array9[@]}"
# "...А с платформы говорят: "Это город Ленинград!"..."
declare -a array10=( ${array0[@]#$zap} )
echo
echo "Элементы массива array10: ${array10[@]}"
# Сравните массивы array7 и array10
# Сравните массивы array8 и array9
# Ответ: в "мягких" кавычках.
exit 0
Разница между ${array_name[@]}и ${array_name[*]}такая же, как между $@ и $*. Эти свойства массивов широко применяются на практике.
# Копирование массивов.
array2=( "${array1[@]}" )
# или
array2="${array1[@]}"
# Добавить элемент.
array=( "${array[@]}" "новый элемент" )
# или
array[${#array[*]}]="новый элемент"
# Спасибо S.C.
Операция подстановки команд -- array=( element1 element2 ... elementN ), позволяет загружать содержимое текстовых файлов в массивы.
#!/bin/bash
filename=sample_file
# cat sample_file
#
# 1 a b c
# 2 d e fg
declare -a array1
array1=( `cat "$filename" | tr '\n' ' '`) # Загрузка содержимого файла
# $filename в массив array1.
# Вывод на stdout.
# с заменой символов перевода строки на пробелы.
echo ${array1[@]} # список элементов массива.
# 1 a b c 2 d e fg
#
# Каждое "слово", в текстовом файле, отделяемое от других пробелами
#+ заносится в отдельный элемент массива.
element_count=${#array1[*]}
echo $element_count # 8
Пример 25-5. Копирование и конкатенация массивов
#! /bin/bash
# CopyArray.sh
#
# Автор: Michael Zick.
# Используется с его разрешения.
# "Принять из массива с заданным именем записать в массив с заданным именем"
#+ или "собственный Оператор Присваивания".
CpArray_Mac() {
# Оператор Присваивания
echo -n 'eval '
echo -n "$2" # Имя массива-результата
echo -n '=( ${'
echo -n "$1" # Имя исходного массива
echo -n '[@]} )'
# Все это могло бы быть объединено в одну команду.
# Это лишь вопрос стиля.
}
declare -f CopyArray # "Указатель" на функцию
CopyArray=CpArray_Mac # Оператор Присваивания
Hype()
{
# Исходный массив с именем в $1.
# (Слить с массивом, содержащим "-- Настоящий Рок-н-Ролл".)
# Вернуть результат в массиве с именем $2.
local -a TMP
local -a hype=( -- Настоящий Рок-н-Ролл )
$($CopyArray $1 TMP)
TMP=( ${TMP[@]} ${hype[@]} )
$($CopyArray TMP $2)
}
declare -a before=( Advanced Bash Scripting )
declare -a after
echo "Массив before = ${before[@]}"
Hype before after
echo "Массив after = ${after[@]}"
# Еще?
echo "Что такое ${after[@]:4:2}?"
declare -a modest=( ${after[@]:2:1} ${after[@]:3:3} )
# ---- выделение подстроки ----
echo "Массив Modest = ${modest[@]}"
# А что в массиве 'before' ?
echo "Массив Before = ${before[@]}"
exit 0
--
Массивы допускают перенос хорошо известных алгоритмов в сценарии на языке командной оболочки. Хорошо ли это -- решать вам.
Пример 25-6. Старая, добрая: "Пузырьковая" сортировка
#!/bin/bash
# bubble.sh: "Пузырьковая" сортировка.
# На каждом проходе по сортируемому массиву,
#+ сравниваются два смежных элемента, и, если необходимо, они меняются местами.
# В конце первого прохода, самый "тяжелый" элемент "опускается" в конец массива.
# В конце второго прохода, следующий по "тяжести" элемент занимает второе место снизу.
# И так далее.
# Каждый последующий проход требует на одно сравнение меньше предыдущего.
# Поэтому вы должны заметить ускорение работы сценария на последних проходах.
exchange()
{
# Поменять местами два элемента массива.
local temp=${Countries[$1]} # Временная переменная
Countries[$1]=${Countries[$2]}
Countries[$2]=$temp
return
}
declare -a Countries # Объявление массива,
#+ необязательно, поскольку он явно инициализируется ниже.
# Допустимо ли выполнять инициализацию массива в нескольки строках?
# ДА!
Countries=(Нидерланды Украина Заир Турция Россия Йемен Сирия \
Бразилия Аргентина Никарагуа Япония Мексика Венесуэла Греция Англия \
Израиль Перу Канада Оман Дания Уэльс Франция Кения \
Занаду Катар Лихтенштейн Венгрия)
# "Занаду" -- это мифическое государство, где, согласно Coleridge,
#+ Kubla Khan построил величественный дворец.
clear # Очистка экрана.
echo "0: ${Countries[*]}" # Список элементов несортированного массива.
number_of_elements=${#Countries[@]}
let "comparisons = $number_of_elements - 1"
count=1 # Номер прохода.
while [ "$comparisons" -gt 0 ] # Начало внешнего цикла
do
index=0 # Сбросить индекс перед началом каждого прохода.
while [ "$index" -lt "$comparisons" ] # Начало внутреннего цикла
do
if [ ${Countries[$index]} \> ${Countries[`expr $index + 1`]} ]
# Если элементы стоят не по порядку...
# Оператор \> выполняет сравнение ASCII-строк
#+ внутри одиночных квадратных скобок.
# if [[ ${Countries[$index]} > ${Countries[`expr $index + 1`]} ]]
#+ дает тот же результат.
then
exchange $index `expr $index + 1` # Поменять местами.
fi
let "index += 1"
done # Конец внутреннего цикла
let "comparisons -= 1" # Поскольку самый "тяжелый" элемент уже "опустился" на дно,
#+ то на каждом последующем проходе нужно выполнять на одно сравнение меньше.
echo
echo "$count: ${Countries[@]}" # Вывести содержимое массива после каждого прохода.
echo
let "count += 1" # Увеличить счетчик проходов.
done # Конец внешнего цикла
exit 0
--
Можно ли вложить один массив в другой?
#!/bin/bash
# Вложенный массив.
# Автор: Michael Zick.
AnArray=( $(ls --inode --ignore-backups --almost-all \
--directory --full-time --color=none --time=status \
--sort=time -l ${PWD} ) ) # Команды и опции.
# Пробелы важны . . .
SubArray=( ${AnArray[@]:11:1} ${AnArray[@]:6:5} )
# Массив имеет два элемента, каждый из которых, в свою очередь, является массивом.
echo "Текущий каталог и дата последнего изменения:"
echo "${SubArray[@]}"
exit 0
--
Вложенные массивы, в комбинации с косвенными ссылками, предоставляют в распоряжение программиста ряд замечательных возможностей
Пример 25-7. Вложенные массивы и косвенные ссылки
#!/bin/bash
# embedded-arrays.sh
# Вложенные массивы и косвенные ссылки.
# Автор: Dennis Leeuw.
# Используется с его разрешения.
# Дополнен автором документа.
ARRAY1=(
VAR1_1=value11
VAR1_2=value12
VAR1_3=value13
)
ARRAY2=(
VARIABLE="test"
STRING="VAR1=value1 VAR2=value2 VAR3=value3"
ARRAY21=${ARRAY1[*]}
) # Вложение массива ARRAY1 в массив ARRAY2.
function print () {
OLD_IFS="$IFS"
IFS=$'\n' # Вывод каждого элемента массива
#+ в отдельной строке.
TEST1="ARRAY2[*]"
local ${!TEST1} # Посмотрите, что произойдет, если убрать эту строку.
# Косвенная ссылка.
# Позволяет получить доступ к компонентам $TEST1
#+ в этой функции.
# Посмотрим, что получилось.
echo
echo "\$TEST1 = $TEST1" # Просто имя переменной.
echo; echo
echo "{\$TEST1} = ${!TEST1}" # Вывод на экран содержимого переменной.
# Это то, что дает
#+ косвенная ссылка.
echo
echo "-------------------------------------------"; echo
echo
# Вывод переменной
echo "Переменная VARIABLE: $VARIABLE"
# Вывод элементов строки
IFS="$OLD_IFS"
TEST2="STRING[*]"
local ${!TEST2} # Косвенная ссылка (то же, что и выше).
echo "Элемент VAR2: $VAR2 из строки STRING"
# Вывод элемента массива
TEST2="ARRAY21[*]"
local ${!TEST2} # Косвенная ссылка.
echo "Элемент VAR1_1: $VAR1_1 из массива ARRAY21"
}
echo
exit 0
--
С помощью массивов, на языке командной оболочки, вполне возможно реализовать алгоритм Решета Эратосфена . Конечно же -- это очень ресурсоемкая задача. В виде сценария она будет работать мучительно долго, так что лучше всего реализовать ее на каком либо другом, компилирующем, языке программирования, таком как C.
Читать дальшеИнтервал:
Закладка: