O que o% faz nas sequências do shell do Linux?

26

No shell do Linux, o que o% faz, como em:

for file in *.png.jpg; do
  mv "$file" "${file%.png.jpg}.jpg"
done
    
por Nissim Kaufmann 30.08.2016 / 22:22

4 respostas

27

Quando % é usado no padrão ${variable%substring} , ele retornará o conteúdo de variable com a menor ocorrência de substring excluída da parte de trás de variable .

Esta função suporta padrões curinga - é por isso que aceita asterisco como um substituto para zero ou mais caracteres.

Deve-se mencionar que isso é específico do Bash - outros shells linux não precisam necessariamente conter essa função.

Se você quiser saber mais sobre manipulação de string no Bash, sugiro que leia este página. Entre outras funções úteis, por exemplo, explica o que faz %% :)

Edit: Esqueci de mencionar que quando é usado no padrão $((variable%number)) ou $((variable1%$variable2)) , o caracter % funcionará como operador de modulo. DavidPostill tem links de documentação mais específicos em sua resposta.

Quando % é usado em contextos diferentes, deve ser reconhecido apenas como caracteres regulares.

    
por 30.08.2016 / 22:37
9

Bash Reference Manual: Shell Parameter Expansion

${parameter%word}
${parameter%%word}

The word is expanded to produce a pattern just as in filename expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the value of parameter with the shortest matching pattern (the ‘%’ case) or the longest matching pattern (the ‘%%’ case) deleted. If parameter is ‘@’ or ‘*’, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with ‘@’ or ‘*’, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

    
por 30.08.2016 / 22:36
6

Ao experimentar, descubro que uma correspondência após% é descartada, quando a string é colocada entre chaves (chaves).

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

Aqui está a saída:

abcd
abcd%
abcd
abcd

ab
abcd
ab
abcd
abcd%c*
    
por 30.08.2016 / 22:28
6

No shell do Linux ( bash ), o que faz % ?

for file in *.png.jpg; do
  mv "$file" "${file%.png.jpg}.jpg"
done

Neste caso específico, o operador % é correspondente (nota Também pode ser um operador módulo ).

Operador de correspondência de padrões

${var%$Pattern}, ${var%%$Pattern}

${var%$Pattern} Remove from $var the shortest part of $Pattern that matches the back end of $var.

${var%%$Pattern} Remove from $var the longest part of $Pattern that matches the back end of $var.

Example: Pattern matching in parameter substitution

#!/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

Fonte Substituição de parâmetros

Operador Modulo

%

modulo, or mod (returns the remainder of an integer division operation)

bash$ expr 5 % 3
2

5/3 = 1, with remainder 2

Fonte Operadores

    
por 30.08.2016 / 22:40

Tags