Bash – Получить определённые параметры из команды и поместить их в строку

Вопрос или проблема

Я хочу:

  1. получить все параметры команды, кроме первых двух
  2. создать строку с результатом предыдущего шага

Итак, если у меня есть эта команда:

mycommand param1 param2 param3 param4 param5 paramN

Я должен получить эту строку:

"param3 param4 param5 paramN"

Я знаю, что чтобы получить все параметры, кроме первых двух, я могу:

echo "'${@:3}'"

А чтобы поместить все параметры в строку, я могу:

echo "'$*'"

Но я не знаю, как объединить эти два подхода, чтобы достичь того, что я хочу.

В bash, как и в ksh93, откуда bash заимствовал эту синтаксическую конструкцию, просто используйте "${*:3}" (не убирайте кавычки), предварительно установив $IFS на желаемый символ разделителя:

mycommand() {
  local IFS=' ' # первый символ $IFS используется для объединения "$*"
  printf 'Третий с конца, объединенный пробелами: "%s"\n' "${*:3}"
}
bash-5.2$ mycommand param1 param2 param3 param4 param5 paramN
Третий с конца, объединенный пробелами: "param3 param4 param5 paramN"

Это также будет работать в последних версиях zsh, но там лучше использовать ${(j[ ])@[3,-1]}, где вы можете явно указать, как элементы должны быть объединены, не изменяя глобальный параметр, и используя синтаксис $array[first,last], а не ${array[*]:offset:length} из ksh93, который конфликтует с модификаторами csh и Bourne’s ${var:-value} (но в итоге zsh поддержал это с ограничениями несколько десятилетий спустя для совместимости с ksh93/bash).

Это можно сделать с помощью команды shift:

# cat a.sh
shift 2; echo "$*"

или

shift; shift; echo "$*"  

Второй вариант дает ожидаемый результат, когда количество параметров меньше 2 (на моей bash v4.4.12)

# ./a.sh 1 2 3 4 5 6
3 4 5 6

Чтобы поместить их в переменную:

shift 2; a="$*"

или

shift; shift; a="$*"

(смотрите выше)

Ответ или решение

В Bash вы можете легко извлечь параметры из команды, пропустив первые два и сформировав строку из оставшихся. Рассмотрим, как это можно сделать с использованием различных методов.

Способ 1: Использование переменной IFS

Можно использовать переменную IFS для установки символа-разделителя и извлечения параметров с помощью printf. Вот пример функции, которая выполняет эту задачу:

mycommand() {
  local IFS=' '  # Установим пробел как разделитель
  printf 'Третий и последующие параметры, объединенные пробелами: "%s"\n' "${*:3}"
}

Пример использования:

mycommand param1 param2 param3 param4 param5 paramN

Результат:

Третий и последующие параметры, объединенные пробелами: "param3 param4 param5 paramN"

Способ 2: Использование команды shift

Еще один способ – использовать команду shift, чтобы "сдвинуть" параметры и затем вывести оставшиеся:

shift 2           # Сдвигаем параметры, отбрасывая первые два
echo "$*"        # Выводим оставшиеся параметры

Пример использования:

mycommand() {
  shift 2        # Убираем первые два параметра
  a="$*"        # Сохраняем оставшиеся параметры в переменной a
  echo "$a"
}

mycommand param1 param2 param3 param4 param5 paramN

Результат:

param3 param4 param5 paramN

Также можно использовать «двойной сдвиг» в случае, если вы не уверены о количестве параметров, передаваемых в сценарий:

shift; shift    # Сдвиг двух параметров
echo "$*"

В этом случае, если передано менее двух параметров, Bash не выдаст ошибку и просто вернет пустую строку.

Примечание

В зависимости от версии Bash и других настроек, может быть целесообразно обрабатывать случаи, когда передано недостаточно параметров, чтобы избежать неожиданных результатов.

Эти методы позволяют вам легко получить нужные параметры и объединить их в строку, подходящую для дальнейшего использования в вашем сценарии.

Оцените материал
Добавить комментарий

Капча загружается...