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

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 63 64 65 66 67 68 69 70 71 ... 96
Перейти на страницу:

Пример 25-3. Некоторые специфичные особенности массивов

#!/bin/bash

declare -a colors

# Допускается объявление массива без указания его размера.

echo "Введите ваши любимые цвета (разделяя их пробелами)."

read -a colors # Введите хотя бы 3 цвета для демонстрации некоторых свойств массивов.

# Специфический ключ команды 'read',

#+ позволяющий вводить несколько элементов массива.

echo

element_count=${#colors[@]}

# Получение количества элементов в массиве.

# element_count=${#colors[*]} -- дает тот же результат.

#

# Переменная "@" позволяет "разбивать" строку в кавычках на отдельные слова

#+ (выделяются слова, разделенные пробелами).

index=0

while [ "$index" -lt "$element_count" ]

do # Список всех элементов в массиве.

echo ${colors[$index]}

let "index = $index + 1"

done

# Каждый элемент массива выводится в отдельной строке.

# Если этого не требуется, то используйте echo -n "${colors[$index]} "

#

# Эквивалентный цикл "for":

# for i in "${colors[@]}"

# do

# echo "$i"

# done

# (Спасибо S.C.)

echo

# Еще один, более элегантный, способ вывода списка всех элементов массива.

echo ${colors[@]} # ${colors[*]} дает тот же результат.

echo

# Команда "unset" удаляет элементы из массива, или даже массив целиком.

unset colors[1] # Удаление 2-го элемента массива.

# Тот же эффект дает команда colors[1]=

echo ${colors[@]} # Список всех элементов массива -- 2-й элемент отсутствует.

unset colors # Удаление всего массива.

# Тот же эффект имеют команды unset colors[*]

#+ и unset colors[@].

echo; echo -n "Массив цветов опустошен."

echo ${colors[@]} # Список элементов массива пуст.

exit 0

Как видно из предыдущего примера, обращение к ${array_name[@]} или ${array_name[*]} относится ко всем элементам массива. Чтобы получить количество элементов массива, можно обратиться к ${#array_name[@]} или к ${#array_name[*]}. ${#array_name} -- это длина (количество символов) первого элемента массива, т.е. ${array_name[0]}.

Пример 25-4. Пустые массивы и пустые элементы

#!/bin/bash

# empty-array.sh

# Выражаю свою благодарность Stephane Chazelas за этот пример,

#+ и Michael Zick за его доработку.

# Пустой массив -- это не то же самое, что массив с пустыми элементами.

array0=( первый второй третий )

array1=( '' ) # "array1" имеет один пустой элемент.

array2=( ) # Массив "array2" не имеет ни одного элемента, т.е. пуст.

echo

ListArray()

{

echo

echo "Элементы массива array0: ${array0[@]}"

echo "Элементы массива array1: ${array1[@]}"

echo "Элементы массива array2: ${array2[@]}"

echo

echo "Длина первого элемента массива array0 = ${#array0}"

echo "Длина первого элемента массива array1 = ${#array1}"

echo "Длина первого элемента массива array2 = ${#array2}"

echo

echo "Число элементов в массиве array0 = ${#array0[*]}" # 3

echo "Число элементов в массиве array1 = ${#array1[*]}" # 1 (сюрприз!)

echo "Число элементов в массиве array2 = ${#array2[*]}" # 0

}

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

ListArray

# Попробуем добавить новые элементы в массивы

# Добавление новых элементов в массивы.

array0=( "${array0[@]}" "новый1" )

array1=( "${array1[@]}" "новый1" )

array2=( "${array2[@]}" "новый1" )

ListArray

# или

array0[${#array0[*]}]="новый2"

array1[${#array1[*]}]="новый2"

array2[${#array2[*]}]="новый2"

ListArray

# Теперь представим каждый массив как 'стек' ('stack')

# Команды выше, можно считать командами 'push' -- добавление нового значения на вершину стека

# 'Глубина' стека:

height=${#array2[@]}

echo

echo "Глубина стека array2 = $height"

# Команда 'pop' -- выталкивание элемента стека, находящегося на вершине:

unset array2[${#array2[@]}-1] # Индексация массивов начинается с нуля

height=${#array2[@]}

echo

echo "POP"

echo "Глубина стека array2, после выталкивания = $height"

ListArray

# Вывести только 2-й и 3-й элементы массива array0

from=1 # Индексация массивов начинается с нуля

to=2 #

declare -a array3=( ${array0[@]:1:2} )

echo

echo "Элементы массива array3: ${array3[@]}"

# Замена элементов по шаблону

declare -a array4=( ${array0[@]/второй/2-й} )

echo

echo "Элементы массива array4: ${array4[@]}"

# Замена строк по шаблону

declare -a array5=( ${array0[@]//новый?/старый} )

echo

echo "Элементы массива array5: ${array5[@]}"

# Надо лишь привыкнуть к такой записи...

declare -a array6=( ${array0[@]#*новый} )

echo # Это может вас несколько удивить

echo "Элементы массива array6: ${array6[@]}"

declare -a array7=( ${array0[@]#новый1} )

echo # Теперь это вас уже не должно удивлять

echo "Элементы массива array7: ${array7[@]}"

# Выглядить очень похоже на предыдущий вариант...

declare -a array8=( ${array0[@]/новый1/} )

echo

echo "Элементы массива array8: ${array8[@]}"

# Итак, что вы можете сказать обо всем этом?

# Строковые операции выполняются последовательно, над каждым элементом

#+ в массиве var[@].

# Таким образом, BASH поддерживает векторные операции

# Если в результате операции получается пустая строка, то

#+ элемент массива "исчезает".

# Вопрос: это относится к строкам в "строгих" или "мягких" кавычках?

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[*]} такая же, как между [email protected] и $*. Эти свойства массивов широко применяются на практике.

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

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

1 ... 63 64 65 66 67 68 69 70 71 ... 96
Перейти на страницу:
Тут вы можете бесплатно читать книгу Искусство программирования на языке сценариев командной оболочки - Мендель Купер.
Комментарии