Как добавить префикс ‘-p’ к каждому аргументу в Bash?

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

Как добавить префикс -p к каждому аргументу, переданному в мою функцию?

Изменение самих аргументов и создание нового массива подходят оба варианта.

Это должно хорошо работать даже для сложных аргументов с пробелами и хуже:

#!/bin/bash
new_args=()
for arg
do
    new_args+=( '-p' )
    new_args+=( "$arg" )
done

for arg in "${new_args[@]}"
do
    echo "$arg"
done

Тест:

$ ~/test.sh foo $'bar\n\tbaz bay'
-p
foo
-p
bar
    baz bay

Поместите аргументы в массив и используйте замена параметров оболочки bash на них с заменой в массиве и сопоставлением с префиксом:

ARGS=("$@")
echo ${ARGS[@]/#/-p }

Это заменяет начало каждого аргумента на -p<пробел>.

К сожалению, это не работает правильно, если в ваших аргументах есть пробелы. Пробелы сохраняются правильно с ARGS=("$@"), но не при выполнении ${ARGS[@]/#/-p } замены. Вы можете заключить эту замену в двойные кавычки, но тогда вы получите -p arg1 как один аргумент, а не два.

Если вам не нужно добавлять -p<пробел>, а просто -p, то заключение в двойные кавычки должно сработать. Экспериментируйте с двойными кавычками и без них, чтобы понять, что лучше подходит для вас.

Вы можете сохранить пробелы в ${ARGS[@]/#/-p } замене, если установите переменную IFS в пустую строку!

# пример кода
(
set -- 1 2 3 'arg with spaces' $'bar\n\tbaz bay'
printf 'oldIFS: %q\n' "$IFS"
IFS=""                       
#IFS=" "                       
printf 'newIFS: %q\n' "$IFS"
ARGS=("$@")
ARGS=( ${ARGS[@]/#/-p } )
for ((i=0; i < ${#ARGS[@]}; i++)); do
  echo "$i: ${ARGS[i]}"
done
)

Внутри функции вы можете ограничить область видимости модифицированной переменной IFS для этой функции, используя declare IFS="".

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

Чтобы ответить на вопрос о том, как префиксировать каждый аргумент строкой «-p» в Bash, давайте более подробно рассмотрим способы реализации этого в скрипте. Для достижения цели можно использовать несколько подходов, каждый из которых имеет свои преимущества и недостатки. В этом объяснении основные акценты будут сделаны на контексте, примерах и применении (теория, пример, применение), чтобы обеспечить полное понимание.

Теория

В Bash оболочке есть встроенные механизмы, которые позволяют манипулировать аргументами командной строки, такими как циклы, массивы, а также встроенные инструменты для текстового преобразования. Аргументы, переданные функции или скрипту, можно обработать даже если они содержат сложные включения, такие как пробелы, специальные символы и переводы строки. Основной задачей является добавление префикса «-p» перед каждым аргументом.

Пример и применение

Способ 1: Используя цикл for

Одним из способов достижения данной цели является использование цикла for для прохождения по всем аргументам, добавляя префикс «-p» перед каждым. Этот метод сохраняет пространство аргументов, в том числе пробелы и специальные символы, благодаря правильному оборачиванию аргументов в кавычки:

#!/bin/bash

new_args=()
for arg in "$@"; do
    new_args+=('-p')
    new_args+=("$arg")
done

# Отображение результатов
for arg in "${new_args[@]}"; do
    echo "$arg"
done

В этом скрипте:

  • Используется массив new_args, чтобы хранить новые аргументы.
  • Каждый аргумент обрабатывается в цикле, и добавляется префикс «-p».
  • После обработки, массив new_args выводится на экран, показывая каждую часть как отдельный аргумент.

Способ 2: Используя замещение в массиве

Другим подходом является применение замены элементов массива с использованием встроенной возможности Bash для изменения аргументов:

#!/bin/bash

ARGS=("$@")
ARGS=( "${ARGS[@]/#/-p }" )

# Отображение результатов, чтобы показать каждый элемент отдельно
for arg in "${ARGS[@]}"; do
    echo "$arg"
done

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

Временное изменение IFS

Для корректного восприятия сложных аргументов с пробелами, переводами строк и табуляцией, можно временно изменить значение разделителя полей (IFS) на пустую строку:

#!/bin/bash

(
set -- "$@" 'аргумент с пробелами' $'bar\n\tbaz bay'
IFS=""
ARGS=("$@")
ARGS=( "${ARGS[@]/#/-p }" )

for ((i=0; i < ${#ARGS[@]}; i++)); do
  echo "$i: ${ARGS[i]}"
done
)

В этом примере:

  • Использование IFS как пустой строки позволяет сохранить пространственную структуру сложных аргументов.
  • Скрипт обрабатывает набор аргументов, сохраняя их целостность.

Заключение

Подводя итог, вопрос о добавлении префикса к аргументам в Bash можно решить несколькими способами в зависимости от сложности аргументов и необходимой точности. Классический способ с циклом for является более прямым и понятным. Однако, в случаях необходимости работы с комплексными аргументами, может быть полезно временное манипулирование значением IFS.

Лучше всего выбрать подход, который наиболее подходит под конкретные условия использования и входные данные. Явное понимание работы с массивами и аргументами в Bash значительно упрощает задачи подобной природы.

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

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