Buscar..


Introducción

El carácter $ introduce la expansión de parámetros, la sustitución de comandos o la expansión aritmética. El nombre del parámetro o el símbolo que se expandirá puede incluirse entre llaves, que son opcionales, pero sirven para proteger la variable que se expandirá de los caracteres que la siguen, lo que podría interpretarse como parte del nombre.

Lea más en el manual de usuario de Bash .

Sintaxis

  • $ {parámetro: desplazamiento} # subcadena comenzando en desplazamiento
  • $ {parámetro: desplazamiento: longitud} # subcadena de longitud "longitud" que comienza en desplazamiento
  • $ {# parámetro} # Longitud del parámetro
  • $ {parámetro / patrón / cadena} # Reemplace la primera aparición del patrón con cadena
  • $ {parámetro // patrón / cadena} # Reemplazar todas las apariciones de patrón con cadena
  • $ {parameters / # patrón / cadena} # Reemplazar patrón con cadena si el patrón está al principio
  • $ {parámetro /% patrón / cadena} # Reemplazar patrón con cadena si el patrón está al final
  • $ {parámetro # patrón} # Eliminar la coincidencia más corta del patrón desde el comienzo del parámetro
  • $ {parámetro ## patrón} # Eliminar la coincidencia más larga del patrón desde el comienzo del parámetro
  • $ {parámetro% patrón} # Eliminar la coincidencia más corta del patrón del final del parámetro
  • $ {parámetro %% patrón} # Eliminar la coincidencia más larga del patrón desde el final del parámetro
  • $ {parámetro: -word} # Expandir a palabra si el parámetro no está establecido / no definido
  • $ {parámetro: = palabra} # Expandir a palabra si parámetro no establecido / no definido y establecer parámetro
  • $ {parámetro: + palabra} # Expandir a palabra si el conjunto de parámetros / definido

Subcadenas y subarreglos

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

Las mismas expansiones se aplican si el parámetro es un parámetro posicional o el elemento de una matriz con subíndices :

# 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

Las expansiones análogas se aplican a los parámetros posicionales , donde las compensaciones se basan en una sola:

# 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

La expansión de subcadenas se puede utilizar con matrices indexadas :

# 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

Longitud del parámetro

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

Tenga en cuenta que la longitud en número de caracteres no es necesariamente la misma que la cantidad de bytes (como en UTF-8 donde la mayoría de los caracteres están codificados en más de un byte), ni la cantidad de glifos / grafemas (algunos de los cuales son combinaciones de caracteres), ni es necesariamente el mismo que el ancho de visualización.

# 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

Modificando el caso de los caracteres alfabéticos.

4.0

A mayúsculas

$ 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

A minúsculas

$ 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

Caso de palanca

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

Parámetro indirecto

Bash indirección de Bash permite obtener el valor de una variable cuyo nombre está contenido en otra variable. Ejemplo de variables:

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

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

Algunos ejemplos más que demuestran el uso de expansión indirecta:

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

Un ejemplo más:

$ 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

Sustitución de valor por defecto

${parameter:-word}

Si el parámetro no está definido o es nulo, se sustituye la expansión de la palabra. De lo contrario, se sustituye el valor del parámetro.

$ 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}

Si el parámetro no está definido o es nulo, la expansión de la palabra se asigna al parámetro. El valor del parámetro se sustituye. Los parámetros posicionales y los parámetros especiales no pueden asignarse de esta manera.

$ 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

Error si la variable está vacía o sin configurar

La semántica para esto es similar a la de la sustitución del valor predeterminado, pero en lugar de sustituir un valor predeterminado, se produce un error con el mensaje de error proporcionado. Los formularios son ${VARNAME?ERRMSG} y ${VARNAME:?ERRMSG} . La forma con : será nuestro error si la variable no está definida o está vacío, mientras que la forma sin error sólo si la variable no está definida. Si se produce un error, se emite ERRMSG y el código de salida se establece en 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}"

La ejecución del ejemplo completo sobre cada una de las declaraciones de error de error debe ser comentada para continuar.

Eliminar un patrón desde el principio de una cadena

Partido más corto:

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

Partido más largo:

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

Eliminar un patrón del final de una cadena

Partido más corto:

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

Partido más largo:

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

Reemplazar patrón en cadena

Primer partido:

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

Todos los partidos:

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

Partido al principio:

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

Partido al final:

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

Reemplazar un patrón con nada:

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

Añadir prefijo a los elementos de la matriz:

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

Munging durante la expansión

Las variables no necesariamente tienen que expandirse a sus valores: las subcadenas se pueden extraer durante la expansión, lo que puede ser útil para extraer extensiones de archivo o partes de rutas. Los caracteres globales mantienen sus significados habituales, por lo que .* refiere a un punto literal, seguido de cualquier secuencia de caracteres; No es una expresión regular.

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

También es posible expandir una variable usando un valor predeterminado; digamos que quiero invocar el editor del usuario, pero si no han establecido uno, me gustaría darles vim .

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

Hay dos formas diferentes de realizar esta expansión, que difieren en si la variable relevante está vacía o sin configurar. Usando :- usará el valor predeterminado si la variable no está establecida o está vacía, mientras que - solo usa el valor predeterminado si la variable está desactivada, pero usará la variable si está establecida en la cadena vacía:

$ 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

Similar a los valores por defecto, se pueden dar alternativas; donde se usa un valor predeterminado si una variable particular no está disponible, se usa una alternativa si la variable está disponible.

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

Teniendo en cuenta que estas expansiones se pueden anidar, el uso de alternativas se vuelve particularmente útil al proporcionar argumentos a los indicadores de línea de comando;

$ 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 

Expansión de parámetros y nombres de archivos

Puede usar Bash Parameter Expansion para emular operaciones comunes de procesamiento de nombres de archivo como basename y dirname .

Usaremos esto como nuestro camino de ejemplo:

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

Para emular dirname y devolver el nombre de directorio de una ruta de archivo:

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

Para emular basename $FILENAME y devolver el nombre de archivo de una ruta de archivo:

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

Para emular el basename $FILENAME .txt y devolver el nombre de archivo sin el .txt. extensión:

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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow