En el shell de Linux, qué hace%, como en:
for file in *.png.jpg; do
mv "$file" "${file%.png.jpg}.jpg"
done
Cuando %
se usa en un patrón ${variable%substring}
, devolverá el contenido variable
con la menor ocurrencia de substring
borrado 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.
sh
shell compatible, no solo Bash. (aunque tal vez no en csh
y similares).
%
se utiliza es en especificadores de formato para printf
.
Manual de referencia de Bash: expansión de parámetros de shell
${parameter%word}
${parameter%%word}
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.
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
Aquí está la salida:
abcd
abcd%
abcd
abcd
ab
abcd
ab
abcd
abcd%c*
bash
), ¿qué hace %
?for file in *.png.jpg; do
mv "$file" "${file%.png.jpg}.jpg"
done
En este caso particular, el operador %
es coincidencia de patrones (tenga en cuenta que también puede ser un operador de módulo ).
$ {var% $ Pattern}, $ {var %% $ Pattern}
${var%$Pattern}
Eliminar de$var
la parte más corta de$Pattern
eso coincide con el extremo posterior de$var
.
${var%%$Pattern}
Eliminar de$var
la parte más larga de$Pattern
eso coincide con el extremo posterior de$var
.Ejemplo: coincidencia de patrones en sustitución de parámetros
#!/bin/bash # patt-matching.sh # Pattern matching using the # ## % %% parameter substitution operators. var1=abcd12345abc6789 pattern1=a*c # * (wild card) matches everything between a - c. echo echo "var1 = $var1" # abcd12345abc6789 echo "var1 = ${var1}" # abcd12345abc6789 # (alternate form) echo "Number of characters in ${var1} = ${#var1}" echo echo "pattern1 = $pattern1" # a*c (everything between 'a' and 'c') echo "--------------" echo '${var1#$pattern1} =' "${var1#$pattern1}" # d12345abc6789 # Shortest possible match, strips out first 3 characters abcd12345abc6789 # ^^^^^ |-| echo '${var1##$pattern1} =' "${var1##$pattern1}" # 6789 # Longest possible match, strips out first 12 characters abcd12345abc6789 # ^^^^^ |----------| echo; echo; echo pattern2=b*9 # everything between 'b' and '9' echo "var1 = $var1" # Still abcd12345abc6789 echo echo "pattern2 = $pattern2" echo "--------------" echo '${var1%pattern2} =' "${var1%$pattern2}" # abcd12345a # Shortest possible match, strips out last 6 characters abcd12345abc6789 # ^^^^ |----| echo '${var1%%pattern2} =' "${var1%%$pattern2}" # a # Longest possible match, strips out last 12 characters abcd12345abc6789 # ^^^^ |-------------| # Remember, # and ## work from the left end (beginning) of string, # % and %% work from the right end. echo exit 0
Fuente de sustitución de parámetros
%
módulo o mod (devuelve el resto de una operación de división entera)
bash$ expr 5 % 3 2
5/3 = 1, con el resto 2
Operadores de origen
.*
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?
$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.
%%
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.)