Profundizando un poco más, encontré este comportamiento informado en un Error de FreeBSD:
I've noticed some more issues with the same version of grep. I don't know whether they're related, but I'll append them here for now.
$ printf abc | grep -o '^[a-c]'
should just print 'a', but instead gives three hits, against each letter of the incoming text.
Pero no me queda claro si esto se arreglará ni cuándo.
Попробуйте следующий код:
function happy ()
{
mood="i am $1 happy"
echo "$mood"
}
happy "very"
Или попробуйте вариант ниже,
function happy ()
{
echo "i am $1 happy"
}
happy "very"
Это должно сработать. Будьте очень осторожны с eval
, никогда не используйте eval
для пользовательского ввода, он выполнит что угодно.
mood='i am $1 happy'
happy ()
{
eval echo "$mood"
}
happy "very"
Кажется, вы хотите предоставить пользователю информационные сообщения на разных языках. Вам, вероятно, следует использовать программное обеспечение, специально разработанное для этой цели, если вы хотите сделать это правильно. В мире GNU есть gettext
, которые могут вам пригодиться. (Это не тривиальная задача!)
В приведенном ниже тексте рассматривается вопрос до его обновления.и часть обновленного вопроса (, прежде чем я заметил, что речь идет о предоставлении переведенных сообщений):
Ваш пример не имеет особого смысла, так как ваша функция — это просто псевдоним для echo
. Вы можете легко вызвать свою функцию happy
как
happy "I am $adjective happy" # $adjective would be the string "very"
Кроме того, похоже, что стандартная функция printf
также может быть полезно узнать о:
adjective='very'
printf 'I am %s happy\n' "$adjective"
printf
принимают один или несколько аргументов, где первый — это статическая строка, описывающая выходной формат, возможно, содержащая заполнители, а на остальные аргументы ссылаются заполнители.
Если сообщения являются строками статического формата, просто используйтеprintf
:
apt_get_install ()
{
printf 'Installing %s...\n' "$1"
printf '%s installation started at %s\n' "$1" "$(date)"
apt-get -y install "$1"
printf '%s installation ended at %s\n' "$1" "$(date)"
}
apt_get_install thing
Связанные:
Сzsh
:
mood='I am $1 happy'
happy () {
printf '%s\n' ${(e)mood}
}
happy very
Флаги расширения параметра e
вызывают оценку всех расширений параметров, арифметических расширений и подстановок команд в содержимом переменной. (обратная косая черта перед $
или `
может использоваться для предотвращения их ).
Другой подход, который позволяет избежать опасных вещей, таких как e
или eval
, заключается в использовании gettext
с envsubst
, где вы можете точно указать, что вы хотите заменить:
mood='I am $HOWMUCH happy'
happy() {
HOWMUCH=$1 envsubst <<< "$mood"
}
happy very
Хотя <<<
также является расширением zsh, теперь оно поддерживается несколькими другими оболочками, включая bash
.
Замените envsubst
на envsubst '$HOWMUCH'
, если вы хотите, чтобы были заменены только$HOWMUCH
(или ${HOWMOUCH}
).
С помощью ksh93
или zsh
вы также можете использовать:
mood='I am %1$s happy\n'
happy() {
printf "$mood" "$@"
}
В других реализациях printf
, которые не поддерживают %1$s
, чтобы указать, какой аргумент использовать, в этом конкретном случае вы можете использовать %s
.Если формат имеет %s %s
, первый %s
получает первый аргумент, второй — второй аргумент. Вы можете использовать %2$s %1$s
, чтобы изменить порядок с помощью ksh93
или zsh
. В других реализациях вместо этого можно было бы использовать этот прием:
case $(locale language) in
(*English*) msg="I am in a %s %s%.0s%.0s\n"; mood=mood;;
(*French*) msg="Je suis d'une %.0s%s %s%.0s\n"; mood=humeur;;
esac
mood() {
printf "$msg" "$@" "$@"
}
mood formidable "$mood"
Который будет печатать I'm in a formidable mood
для пользователя, говорящего по-английски -, и Je suis d'une humeur formidable
для пользователя, говорящего по-французски -. Мы передаем аргументы дважды и используем%.0s
(строку, усеченную до нулевой ширины ), чтобы отбросить те, которые нам не нужны, чтобы иметь возможность использовать эти аргументы в другом порядке.