Вопрос или проблема
Как добавить префикс -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 значительно упрощает задачи подобной природы.