Cada vez que busco esto, generalmente encuentro la sección correcta de la página de manual de bash buscando %%o ##, ya que es memorable y lo suficientemente raro como para encontrar la sección correcta rápidamente. man bash/##
Peter Cordes el
3
@PeterCordes Siempre recuerdo esto por "Es 5%, por lo que% está al final y, por lo tanto, se corta desde el final. Y es el # 5, por lo que # está al principio y se corta desde el principio". Pero a veces incluso mezclo esto ...
glglgl
2
@glglgl: en un teclado típico de EE. UU., #está inmediatamente a la izquierda de $, y %está inmediatamente a la derecha. No se necesita mnemónica --- solo mira hacia abajo. (Esa es probablemente al menos parte de por qué se eligieron esos símbolos.)
Kevin J. Chase
@ KevinJ.Chase No todos en el mundo tienen un teclado típico de EE. UU. Pero, de hecho, en un teclado alemán,% también tiene el valor de $, eso podría ser un comienzo para memorizar.
glglgl
Respuestas:
29
Cuando %se usa en un patrón ${variable%substring}, devolverá el contenido variablecon la menor ocurrencia de substringborrado de la parte posterior de variable.
Esta función admite patrones comodín; es por eso que acepta la estrella (asterisco) como un subsistema para cero o más caracteres.
Cabe mencionar que esto es específico de Bash: otros shells de Linux no necesariamente contienen esta función.
Si desea obtener más información sobre la manipulación de cadenas en Bash, le recomiendo leer esta página. Entre otras funciones útiles, por ejemplo, explica qué hace %%:)
Editar: Olvidé mencionar que cuando se usa en patrón $((variable%number))o $((variable1%$variable2))el %personaje funcionará como operador de módulo. DavidPostill tiene enlaces de documentación más específicos en su respuesta.
Cuando %se usa en un contexto diferente, debe reconocerse solo como carácter regular.
El operador admite patrones comodín , no expresiones regulares.
cabeza de jardín
Como mencionó gardenhead: admite patrones globales, no expresiones regulares. En expresión regular, una estrella significa cero o más del carácter anterior.
Los operadores de eliminación de prefijos y sufijos son estándar , por lo que deberían utilizarse en cualquier shshell compatible, no solo Bash. (aunque tal vez no en cshy similares).
ilkkachu
1
Otro contexto en el que %se utiliza es en especificadores de formato para printf.
La palabra se expande para producir un patrón al igual que en la expansión de nombre de archivo. Si el patrón coincide con una parte posterior del valor expandido del parámetro , entonces el resultado de la expansión es el valor del parámetro con el patrón de coincidencia más corto (el ‘%’caso) o el patrón de coincidencia más largo (el ‘%%’caso) eliminado. Si el parámetro es ‘@’o ‘*’,la operación de eliminación de patrón se aplica a cada parámetro posicional a su vez, y la expansión es la lista resultante. Si el parámetro es una variable de matriz con subíndice ‘@’
o‘*’, la operación de eliminación de patrones se aplica a cada miembro de la matriz a su vez, y la expansión es la lista resultante.
NB: algunas expansiones de parámetros que incluyen% son características posix que admiten muchos shells.
kojiro
7
Al experimentar, encuentro que una coincidencia después de% se descarta, cuando la cadena se encierra entre llaves (llaves).
Para ilustrar:
touch abcd # Create file abcd
for file in ab*; do
echo $file # echoes the filename
echo $file% # echoes the filename plus "%"
echo ${file%} # echoes the filename
echo "${file%}" # echoes the filename
echo
echo "${file%c*}" # Discard anything after % matching c*
echo "${file%*}" # * is not greedy
echo ${file%c*} # Without quotes works too
echo "${file%c}" # No match after %, no effect
echo $file%c* # Without {} fails
done
Tal vez lo tengo: ¿esto es para cosas como .*y lo %define como no codicioso, mientras %%que lo hace codicioso? Entonces, en realidad, en el ejemplo de cambio de nombre, no importa si se usa %o no, %%pero si fuera mv "$file" "${file%.*png.jpg}.jpg"(tenga en cuenta el *) el uso de %% cambiaría el nombre de todos los archivos a solo .jpg, ¿verdad?
Thomas Weller
@ThomasWeller Creo que es correcto. Pero no soy un experto en bash.
DavidPostill
Decir "Eliminar ... la parte más corta de $Pattern" es incorrecto ya que la variable $Patternno está definida en el ejemplo, solo se está eliminando el texto "Patrón" $varal hacer ${var%Pattern}o ${var%%Pattern}. Tal vez esto sea solo un error tipográfico, pero es otro ejemplo de que tldp.org está equivocado. BashGuide o Bash Hackers Wiki son referencias mucho mejores en mi humilde opinión.
John B
@JohnB Gracias. Ambos enlaces marcados. He corregido el texto en la respuesta.
%%
o##
, ya que es memorable y lo suficientemente raro como para encontrar la sección correcta rápidamente.man bash
/##
#
está inmediatamente a la izquierda de$
, y%
está inmediatamente a la derecha. No se necesita mnemónica --- solo mira hacia abajo. (Esa es probablemente al menos parte de por qué se eligieron esos símbolos.)Respuestas:
Cuando
%
se usa en un patrón${variable%substring}
, devolverá el contenidovariable
con la menor ocurrencia desubstring
borrado de la parte posterior devariable
.Esta función admite patrones comodín; es por eso que acepta la estrella (asterisco) como un subsistema para cero o más caracteres.
Cabe mencionar que esto es específico de Bash: otros shells de Linux no necesariamente contienen esta función.
Si desea obtener más información sobre la manipulación de cadenas en Bash, le recomiendo leer esta página. Entre otras funciones útiles, por ejemplo, explica qué hace
%%
:)Editar: Olvidé mencionar que cuando se usa en patrón
$((variable%number))
o$((variable1%$variable2))
el%
personaje funcionará como operador de módulo. DavidPostill tiene enlaces de documentación más específicos en su respuesta.Cuando
%
se usa en un contexto diferente, debe reconocerse solo como carácter regular.fuente
sh
shell compatible, no solo Bash. (aunque tal vez no encsh
y similares).%
se utiliza es en especificadores de formato paraprintf
.fuente
Al experimentar, encuentro que una coincidencia después de% se descarta, cuando la cadena se encierra entre llaves (llaves).
Para ilustrar:
Aquí está la salida:
fuente
En Linux shell (
bash
), ¿qué hace%
?En este caso particular, el operador
%
es coincidencia de patrones (tenga en cuenta que también puede ser un operador de módulo ).Operador de coincidencia de patrones
Fuente de sustitución de parámetros
Operador de módulo
Operadores de origen
fuente
.*
y lo%
define como no codicioso, mientras%%
que lo hace codicioso? Entonces, en realidad, en el ejemplo de cambio de nombre, no importa si se usa%
o no,%%
pero si fueramv "$file" "${file%.*png.jpg}.jpg"
(tenga en cuenta el *) el uso de %% cambiaría el nombre de todos los archivos a solo.jpg
, ¿verdad?$Pattern
" es incorrecto ya que la variable$Pattern
no está definida en el ejemplo, solo se está eliminando el texto "Patrón"$var
al hacer${var%Pattern}
o${var%%Pattern}
. Tal vez esto sea solo un error tipográfico, pero es otro ejemplo de que tldp.org está equivocado. BashGuide o Bash Hackers Wiki son referencias mucho mejores en mi humilde opinión.