Поиск…


Вступление

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

Подробнее читайте в руководстве пользователя Bash .

Синтаксис

  • $ {parameter: offset} # Подстрока, начинающаяся со смещения
  • $ {parameter: offset: length} # Подстрока длины «длина», начинающаяся со смещения
  • $ {# parameter} # Длина параметра
  • $ {parameter / pattern / string} # Заменить первое вхождение шаблона на строку
  • $ {parameter // pattern / string} # Заменить все вхождения шаблона в строку
  • $ {parameter / # pattern / string} # Заменить шаблон на строку, если шаблон находится в начале
  • $ {параметр /% pattern / string} # Заменить шаблон на строку, если шаблон находится в конце
  • $ {parameter # pattern} # Удалить кратчайшее соответствие шаблона с начала параметра
  • $ {parameter ## pattern} # Удалить наибольшее совпадение шаблона с начала параметра
  • $ {parameter% pattern} # Удалить кратчайшее совпадение шаблона с конца параметра
  • $ {parameter %% pattern} # Удалить наибольшее совпадение шаблона с конца параметра
  • $ {parameter: -word} # Развернуть до слова, если параметр unset / undefined
  • $ {parameter: = word} # Развернуть до слова, если параметр unset / undefined и установить параметр
  • $ {parameter: + word} # Развернуть до слова, если параметр установлен / определен

Подстроки и подмассивы

var='0123456789abcdef'

# Define a zero-based offset
$ printf '%s\n' "${var:3}"
3456789abcdef

# Offset and length of substring
$ printf '%s\n' "${var:3:4}"
3456
4,2
# Negative length counts from the end of the string
$ printf '%s\n' "${var:3:-5}"
3456789a

# Negative offset counts from the end
# Needs a space to avoid confusion with ${var:-6}
$ printf '%s\n' "${var: -6}"
abcdef

# Alternative: parentheses
$ printf '%s\n' "${var:(-6)}"
abcdef

# Negative offset and negative length
$ printf '%s\n' "${var: -6:-5}"
a

Те же расширения применяются, если параметр является позиционным параметром или элементом подстрочного массива :

# Set positional parameter $1
set -- 0123456789abcdef

# Define offset
$ printf '%s\n' "${1:5}"
56789abcdef

# Assign to array element
myarr[0]='0123456789abcdef'

# Define offset and length
$ printf '%s\n' "${myarr[0]:7:3}"
789

Аналогичные расширения применяются к позиционным параметрам , где смещения однонаправлены:

# Set positional parameters $1, $2, ...
$ set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f

# Define an offset (beware $0 (not a positional parameter)
# is being considered here as well)
$ printf '%s\n' "${@:10}"
0
a
b 
c
d
e
f

# Define an offset and a length
$ printf '%s\n' "${@:10:3}"
0
a
b

# No negative lengths allowed for positional parameters
$ printf '%s\n' "${@:10:-2}"
bash: -2: substring expression < 0

# Negative offset counts from the end
# Needs a space to avoid confusion with ${@:-10:2}
$ printf '%s\n' "${@: -10:2}"
7
8

# ${@:0} is $0 which is not otherwise a positional parameters or part
# of $@
$ printf '%s\n' "${@:0:2}"
/usr/bin/bash
1

Расширение подстроки может использоваться с индексированными массивами :

# Create array (zero-based indices)
$ myarr=(0 1 2 3 4 5 6 7 8 9 a b c d e f)

# Elements with index 5 and higher
$ printf '%s\n' "${myarr[@]:12}"
c
d
e
f

# 3 elements, starting with index 5
$ printf '%s\n' "${myarr[@]:5:3}"
5
6
7

# The last element of the array
$ printf '%s\n' "${myarr[@]: -1}"
f

Длина параметра

# Length of a string
$ var='12345'
$ echo "${#var}"
5

Обратите внимание, что это длина числа символов, которая не обязательно совпадает с количеством байтов (например, в UTF-8, где большинство символов кодируются более чем в одном байте), а также количество глифов / графем (некоторые из которых комбинации символов), и не обязательно совпадает с шириной отображения.

# Number of array elements
$ myarr=(1 2 3)
$ echo "${#myarr[@]}"
3

# Works for positional parameters as well
$ set -- 1 2 3 4
$ echo "${#@}"
4

# But more commonly (and portably to other shells), one would use
$ echo "$#"
4

Изменение случая буквенных символов

4,0

В верхний регистр

$ v="hello"
# Just the first character
$ printf '%s\n' "${v^}"
Hello
# All characters
$ printf '%s\n' "${v^^}"
HELLO
# Alternative
$ v="hello world"
$ declare -u string="$v"
$ echo "$string"
HELLO WORLD

В нижнем регистре

$ v="BYE"
# Just the first character
$ printf '%s\n' "${v,}"
bYE
# All characters
$ printf '%s\n' "${v,,}"
bye
# Alternative
$ v="HELLO WORLD"
$ declare -l string="$v"
$ echo "$string"
hello world

Toggle Case

$ v="Hello World"
# All chars
$ echo "${v~~}"
hELLO wORLD
$ echo "${v~}"
# Just the first char
hello World

Неверный параметр

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

$ red="the color red"
$ green="the color green"

$ color=red
$ echo "${!color}"
the color red
$ color=green
$ echo "${!color}"
the color green

Еще несколько примеров, демонстрирующих использование косвенного расширения:

 $ foo=10
 $ x=foo
 $ echo ${x}      #Classic variable print  
 foo  
 
 $ foo=10
 $ x=foo
 $ echo ${!x}     #Indirect expansion
 10

Еще один пример:

$ argtester () { for (( i=1; i<="$#"; i++ )); do echo "${i}";done; }; argtester -ab -cd -ef 
1   #i expanded to 1 
2   #i expanded to 2
3   #i expanded to 3

$ argtester () { for (( i=1; i<="$#"; i++ )); do echo "${!i}";done; }; argtester -ab -cd -ef 
-ab     # i=1 --> expanded to $1 ---> expanded to first argument sent to function
-cd     # i=2 --> expanded to $2 ---> expanded to second argument sent to function
-ef     # i=3 --> expanded to $3 ---> expanded to third argument sent to function

Замена значения по умолчанию

${parameter:-word}

Если параметр не задан или нулевым, заменяется слово. В противном случае значение параметра заменяется.

$ unset var
$ echo "${var:-XX}"     # Parameter is unset -> expansion XX occurs
XX
$ var=""                # Parameter is null -> expansion XX occurs
$ echo "${var:-XX}"
XX
$ var=23                # Parameter is not null -> original expansion occurs
$ echo "${var:-XX}"
23
${parameter:=word}

Если параметр не задан или null, расширение слова присваивается параметру. Затем значение параметра заменяется. Таким образом, нельзя назначать позиционные параметры и специальные параметры.

$ unset var
$ echo "${var:=XX}"     # Parameter is unset -> word is assigned to XX
XX
$ echo "$var"
XX
$ var=""                # Parameter is null -> word is assigned to XX
$ echo "${var:=XX}"
XX
$ echo "$var"
XX
$ var=23                # Parameter is not null -> no assignment occurs
$ echo "${var:=XX}"
23
$ echo "$var"
23

Ошибка, если переменная пуста или не установлена

Семантика для этого аналогична семантике замещения по умолчанию, но вместо того, чтобы подставлять значение по умолчанию, она выдает ошибку с предоставленным сообщением об ошибке. Формы: ${VARNAME?ERRMSG} и ${VARNAME:?ERRMSG} . Форма с : будет ошибкой нашей, если переменная не установлена или пуста , тогда как форма без ошибок будет только выходить из строя, если переменная не установлена . Если ERRMSG ошибка, ERRMSG а код выхода - 1 .

#!/bin/bash
FOO=
# ./script.sh: line 4: FOO: EMPTY
echo "FOO is ${FOO:?EMPTY}"
# FOO is 
echo "FOO is ${FOO?UNSET}"
# ./script.sh: line 8: BAR: EMPTY
echo "BAR is ${BAR:?EMPTY}"
# ./script.sh: line 10: BAR: UNSET
echo "BAR is ${BAR?UNSET}"

Запустите полный пример выше каждого из операторов эхо-сообщений об ошибке, которые необходимо прокомментировать, чтобы продолжить.

Удаление шаблона с начала строки

Наименьшее совпадение:

$ a='I am a string'
$ echo "${a#*a}"
m a string

Наибольшее совпадение:

$ echo "${a##*a}"
 string

Удаление шаблона с конца строки

Наименьшее совпадение:

$ a='I am a string'
$ echo "${a%a*}"
I am 

Наибольшее совпадение:

$ echo "${a%%a*}"
I 

Заменить шаблон в строке

Первый матч:

$ a='I am a string'
$ echo "${a/a/A}"
I Am a string

Все совпадения:

$ echo "${a//a/A}"
I Am A string

Матч в начале:

$ echo "${a/#I/y}"
y am a string

Матч в конце:

$ echo "${a/%g/N}"
I am a strinN

Заменить шаблон ничем:

$ echo "${a/g/}"
I am a strin

Добавить префикс в элементы массива:

$ A=(hello world)
$ echo "${A[@]/#/R}"
Rhello Rworld

Мутирование во время расширения

Переменные не обязательно должны расширяться до их значений - подстроки могут быть извлечены во время расширения, что может быть полезно для извлечения расширений файлов или частей путей. Глобущие символы сохраняют свои обычные значения, поэтому .* Относится к буквальной точке, за которой следует любая последовательность символов; это не регулярное выражение.

$ v=foo-bar-baz
$ echo ${v%%-*}
foo
$ echo ${v%-*}
foo-bar
$ echo ${v##*-}
baz
$ echo ${v#*-}
bar-baz

Также возможно расширить переменную с использованием значения по умолчанию - например, я хочу вызвать редактор пользователя, но если они не установили его, я бы хотел дать им vim .

$ EDITOR=nano
$ ${EDITOR:-vim} /tmp/some_file
# opens nano
$ unset EDITOR
$ $ ${EDITOR:-vim} /tmp/some_file
# opens vim

Существует два разных способа выполнения этого расширения, которые отличаются тем, что соответствующая переменная пуста или не установлена. Использование :- будет использовать значение по умолчанию, если переменная является либо незамкнутой, либо пустой, тогда как - используется только по умолчанию, если переменная не установлена, но будет использовать переменную, если она установлена ​​в пустую строку:

$ a="set"
$ b=""
$ unset c
$ echo ${a:-default_a} ${b:-default_b} ${c:-default_c}
set default_b default_c
$ echo ${a-default_a} ${b-default_b} ${c-default_c}
set default_c

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

$ a="set"
$ b=""
$ echo ${a:+alternative_a} ${b:+alternative_b}
alternative_a

Отмечая, что эти расширения могут быть вложенными, использование альтернатив становится особенно полезным при подаче аргументов в флаги командной строки;

$ output_file=/tmp/foo
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget -o /tmp/foo www.stackexchange.com
$ unset output_file
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget  www.stackexchange.com 

Расширение параметров и имена файлов

Вы можете использовать Bash Parameter Expansion для эмуляции общих операций обработки имен файлов, таких как basename и dirname .

Мы будем использовать это как наш пример:

FILENAME="/tmp/example/myfile.txt"

Чтобы эмулировать имя dirname и вернуть имя каталога пути к файлу:

echo "${FILENAME%/*}"
#Out: /tmp/example

Чтобы эмулировать basename $FILENAME и вернуть имя файла пути к файлу:

echo "${FILENAME##*/}"
#Out: myfile.txt

Чтобы эмулировать basename $FILENAME .txt и вернуть имя файла без .txt. расширение:

BASENAME="${FILENAME##*/}"
echo "${BASENAME%%.txt}"
#Out: myfile


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow