26

В оболочке Linux, что делает%, как в:

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

4 ответа4

28

Когда % используется в шаблоне ${variable%substring} он вернет содержимое variable с кратчайшим вхождением substring удаленной из задней части variable .

Эта функция поддерживает шаблоны подстановочных знаков - поэтому она принимает звездочку (звездочку) в качестве замены для нуля или более символов.

Следует отметить, что это специфично для Bash - другие оболочки Linux не обязательно содержат эту функцию.

Если вы хотите узнать больше о работе со строками в Bash, я настоятельно рекомендую прочитать эту страницу. Среди других полезных функций это, например, объясняет, что делает %% :)

Редактировать: я забыл упомянуть, что когда он используется в шаблоне $((variable%number)) или $((variable1%$variable2)) символ % будет функционировать как оператор по модулю. DavidPostill имеет более конкретные ссылки на документацию в своем ответе.

Когда % используется в другом контексте, он должен распознаваться только как обычный символ.

9

Справочное руководство Bash: Расширение параметров оболочки

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

Слово раскрывается для создания шаблона, как в расширении имени файла. Если шаблон соответствует завершающей части расширенного значения параметра, то результатом расширения является значение параметра с самым коротким совпадающим шаблоном (случай ‘%’ ) или самым длинным совпадающим шаблоном (случай ‘%%’ ) удален. Если параметром является ‘@’ или ‘*’, операция удаления шаблона применяется по очереди к каждому позиционному параметру, и расширение является результирующим списком. Если параметром является переменная массива, подписанная с помощью ‘@’ или ‘*’, операция удаления шаблона применяется по очереди к каждому члену массива, и расширение является результирующим списком.

6

Экспериментируя, я обнаружил, что совпадение после% отбрасывается, когда строка заключена в фигурные скобки (фигурные скобки).

Проиллюстрировать:

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

Вот вывод:

abcd
abcd%
abcd
abcd

ab
abcd
ab
abcd
abcd%c*
6

В оболочке Linux (bash), что делает % ?

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

В этом конкретном случае % является оператором сопоставления с образцом (обратите внимание, что он также может быть оператором по модулю ).


Оператор сопоставления с образцом

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

${var%$Pattern} Удалите из $var самую короткую часть $Pattern , соответствующую внутреннему концу $var .

${var%%$Pattern} Удалите из $var самую длинную часть $Pattern , соответствующую внутреннему концу $var .

Пример: сопоставление с образцом при подстановке параметров

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

Подстановка исходного параметра


Оператор по модулю

%

по модулю или mod (возвращает остаток от операции целочисленного деления)

bash$ expr 5 % 3
2

5/3 = 1, с остатком 2

Операторы источника

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .