- Вопрос или проблема
- Больше примеров срезов массивов в bash
- Ещё напоминания о массивах для себя:
- Запустите всё
- Ссылки
- Ответ или решение
- Как получить срез позиционных параметров в Bash
- Обзор позиционных параметров
- Синтаксис для получения срезов
- Примеры использования
- Пример функции с использованием среза
- Обработка срезов в функции
- Заключение
- Ресурсы для дальнейшего изучения
Вопрос или проблема
Как мне получить часть $@
в Bash, не копируя сначала все позиционные параметры в другой массив, как это?
argv=( "$@" )
echo "${argv[@]:2}";
Вы можете использовать тот же формат, что и для любого другого массива. Чтобы извлечь 2-й и 3-й элементы из $@
, вы можете сделать следующее:
echo "${@:1:2}"
- -
| |----> длина среза
|------> начальный индекс среза
Больше примеров срезов массивов в bash
Вместо того чтобы использовать some_array_variable
в вашем коде (argv
в вашем случае), просто используйте @
на месте этого имени переменной. Символ @
представляет массив входных аргументов, и вы можете обращаться с ним так же, как и с любым другим массивом. Смущение вызывает то, что мы привыкли видеть его почти всегда в паре с символом $
вот так: $@
, и поэтому не осознаем, что символ @
это сам массив, и его можно использовать отдельно как переменную массива.
Итак, вот некоторые примеры:
Срез из массива входных аргументов, @
, который обычно видно и который просто доступен как $@
:
# базовый формат среза массива 1: взять определённую длину, начиная с определённого
# индекса
echo "${@:2:5}"
# │ │
# │ └────> длина среза
# └──────> начальный индекс среза
# базовый формат среза массива 2: взять все оставшиеся элементы массива, начиная с
# определённого индекса и до конца
echo "${@:2}"
# │
# │
# └──────> начальный индекс среза
Ещё напоминания о массивах для себя:
Следующие напоминания о массивах будут полезны и другим, кто зашёл на эту страницу.
# сохранить срез из массива в новый массив
new_array=("${@:4}")
# вывести весь массив (используйте "*" для генерации списка
# с пробелами между элементами, а не "@", что будет генерировать отдельные аргументы)
echo "new_array = ${new_array[*]}"
Вот пример запуска с универсальным срезом массива и доступом к элементам массива в bash, вдохновлённый этим источником:
(Используйте @
как массив входных аргументов, если это необходимо, вместо a
ниже, в зависимости от вашего случая использования)
a=(one two three four five six) # определить новый массив, `a`, с 6 элементами
echo "$a" # вывести первый элемент массива a
echo "${a}" # вывести первый элемент массива a
echo "${a[0]}" # вывести первый элемент массива a
echo "${a[1]}" # вывести *второй* элемент массива a
echo "${#a[@]}" # вывести количество элементов в массиве a
echo "${a[@]:1:3}" # вывести со 2-го по 4-й элементы; то есть 3 элемента
# начиная с индекса 1, включая, то есть: индексы 1, 2 и 3
# (вывод: `two three four`)
echo "${a[@]:1}" # вывести со 2-го элемента и далее
Запустите всё
Скопируйте и вставьте все части кода выше в файл с именем array_slicing_demo.sh
, и пометьте его как исполняемый с помощью chmod +x array_slicing_demo.sh
, чтобы вы могли его запустить. Или просто загрузите мой демон array_slicing_demo.sh из моего eRCaGuy_hello_world репозитория здесь.
Затем выполните его следующим образом:
./array_slicing_demo.sh a b c d e f g h i j k
…и вы увидите следующий вывод:
b c d e f b c d e f g h i j k new_array = d e f g h i j k one one one two 6 two three four two three four five six
Ссылки
Ключевые слова: доступ к массивам в bash; индексация массивов bash; доступ к элементам в массивах bash; срез массивов bash; вывод массивов в bash; вывод элементов массива в bash
Я обычно делаю так:
somefunc() {
local message="$1"
shift
echo "message = $message"
echo "other = $@"
}
somefunc first second third goforth
что напечатает:
message = first
other = second third goforth
Вы можете развить эту концепцию, сделав shift
после второго, третьего и так далее аргумента
Что касается параметров функций, ответ с echo "${@:1:2}"
вообще не сработал для меня. Кроме того, я хотел обрезать первый элемент, так как это был другой параметр. Что сработало:
function foo(){ #принимает один параметр + массив параметров
local param1="$1". #первый параметр
local -a tmp=( "${@}" ) #копируем все параметры
local -a rem_params=( "${tmp[@]:1}") #обрезаем первый:работает!
# local -a rem_params=( "${@[@]:1}" ) #НЕ РАБОТАЛО, ОШИБКА
# local -a rem_params=( "{@:1}" ) #НЕ ОТРЕЗАЛО
echo "${rem_params[@]}"
}
Возможно, я напишу, чтобы протестировать, как это работает с позиционными аргументами на уровне скрипта, но сейчас нет времени.
Ответ или решение
Как получить срез позиционных параметров в Bash
В Bash существует несколько способов работы с позиционными параметрами, но одной из наиболее популярных задач является извлечение среза из массивов аргументов командной строки без необходимости их предварительного копирования в другой массив. Рассмотрим, как это можно сделать эффективно.
Обзор позиционных параметров
Позиционные параметры в Bash обозначаются как $@
, $1
, $2
и т. д. $@
представляет собой массив всех переданных аргументов. Несмотря на то что $@
часто используется для обращения к позиционным параметрам, его можно применять аналогично любому другому массиву, что может создавать путаницу.
Синтаксис для получения срезов
Чтобы выполнить срез позиционных параметров, можно воспользоваться следующей конструкцией:
echo "${@:starting_index:length}"
- starting_index — индекс, с которого начинается срез (обратите внимание, что индексация начинается с нуля).
- length — количество элементов, которые вы хотите извлечь из массива.
Если нужно извлечь все оставшиеся элементы начиная с определённого индекса, используйте следующий синтаксис:
echo "${@:starting_index}"
Примеры использования
- Извлечение первого и второго аргументов:
echo "${@:1:2}" # Это выведет второй и третий аргументы
- Извлечение аргументов начиная с третьего:
echo "${@:2}" # Это выведет все аргументы начиная с третьего
Пример функции с использованием среза
Давайте рассмотрим пример функции, которая принимает один параметр и массив остальных параметров:
somefunc() {
local message="$1"
shift
echo "message = $message"
echo "other = $@"
}
Вызывая эту функцию:
somefunc first second third goforth
Вы получите следующий вывод:
message = first
other = second third goforth
Обработка срезов в функции
Если вам нужно работать с массивами в функции, можно использовать срезы, как показано в следующем примере:
function foo() {
local param1="$1" # Первый параметр
local -a rem_params=( "${@:2}" ) # Срез оставшихся параметров
echo "${rem_params[@]}"
}
foo first second third forth
В этом примере функция foo
извлекает все аргументы, начиная со второго, и выводит их.
Заключение
Таким образом, работа с позиционными параметрами в Bash становится гораздо проще, если вы знаете, как использовать срезы и массивы. Это позволяет избежать ненужного копирования параметров в новые массивы, что, в свою очередь, делает ваш код более эффективным и читаемым.
Эти приёмы могут быть полезны не только в скриптах, но и в более крупных проектах, где необходимо обрабатывать множество параметров, передаваемых функции или скрипту. Попробуйте применить эти методы в своих проектах, и вы заметите, как они упрощают вашу работу с аргументами командной строки.
Ресурсы для дальнейшего изучения
Следуя этому руководству, вы сможете более эффективно работать с позиционными параметрами и добавлять гибкость в ваши скрипты Bash.