Каждый раз, когда я просматриваю это, я обычно нахожу правильный раздел справочной страницы bash, ища %%или ##, так как это запоминающееся и достаточно редкое место, чтобы быстро найти нужный раздел. man bash/##
Питер Кордес
3
@PeterCordes Я всегда вспоминаю это как «Это 5%, поэтому% находится в конце и, следовательно, сокращается с конца. И это # 5, поэтому # находится в начале и сокращается с начала». Но иногда я даже
путаю
2
@glglgl: На типичной клавиатуре США, #находится сразу слева от $, и %сразу же справа. Мнемоника не нужна - просто посмотрите вниз. (Это, вероятно, по крайней мере, часть того, почему эти символы были выбраны.)
Кевин Дж. Чейз,
@ KevinJ.Chase Не у всех в мире есть типичная клавиатура США. Но на немецкой клавиатуре, действительно,% также прав от $, что может стать началом для запоминания.
glglgl
Ответы:
29
Когда %используется в шаблоне, ${variable%substring}он будет возвращать содержимое variableс кратчайшим вхождением, substringудаленным из задней части variable.
Эта функция поддерживает шаблоны подстановочных знаков - поэтому она принимает звездочку (звездочку) в качестве замены для нуля или более символов.
Следует отметить, что это специфично для Bash - другие оболочки linux не обязательно содержат эту функцию.
Если вы хотите узнать больше о работе со строками в Bash, я настоятельно рекомендую прочитать эту страницу. Среди других полезных функций это, например, объясняет, что делает %%:)
Изменить: Я забыл упомянуть , что , когда он используется в шаблоне $((variable%number))или персонаж будет функционировать в качестве оператора по модулю. DavidPostill имеет более конкретные ссылки на документацию в своем ответе.$((variable1%$variable2))%
Когда %используется в другом контексте, он должен распознаваться только как обычный символ.
Оператор поддерживает шаблоны подстановочных знаков , а не регулярные выражения.
садовник
Как упоминалось gardenhead - он поддерживает шаблоны глобуса, а не регулярные выражения. В регулярном выражении звезда означает ноль или более предыдущего символа.
Операторы удаления префиксов и суффиксов являются стандартными , поэтому их следует использовать в любой sh-совместимой оболочке, а не только в Bash. (хотя, возможно, не в cshи тому подобное).
ilkkachu
1
Другой контекст, в котором %используется, находится в спецификаторах формата для printf.
Слово раскрывается , чтобы получить шаблон так же , как в расширении имени файла. Если шаблон соответствует завершающей части расширенного значения параметра , то результатом расширения является значение параметра с удаленным самым коротким соответствующим шаблоном ( ‘%’регистр) или самым длинным соответствующим шаблоном ( ‘%%’регистр). Если параметр равен ‘@’или ‘*’,операция удаления шаблона применяется к каждому позиционному параметру по очереди, и расширение является результирующим списком. Если параметр является переменной массива, подписанной с ‘@’
или‘*’, операция удаления шаблона применяется к каждому члену массива по очереди, и расширение является результирующим списком.
Примечание: некоторые расширения параметров, включая%, - это функции posix, которые поддерживаются многими оболочками.
Кодзиро
7
Экспериментируя, я обнаружил, что совпадение после% отбрасывается, когда строка заключена в фигурные скобки (фигурные скобки).
Проиллюстрировать:
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
Может быть, я понял: это для таких вещей, как .*и %определяет, что это не жадный, тогда как %%делает его жадным? Так что на самом деле в примере переименования не имеет значения, использовать %или использовать ( %%но mv "$file" "${file%.*png.jpg}.jpg"обратите внимание на *), используя %%, переименуйте все файлы просто .jpg, верно?
Томас Веллер
@ThomasWeller Я думаю, это правильно. Но я не эксперт по Bash.
ДэвидПостилл
Сказать «Удалить ... самую короткую часть $Pattern» неверно, так как переменная $Patternне определена в примере, только текст «Шаблон» удаляется $varпри выполнении ${var%Pattern}или ${var%%Pattern}. Может быть, это просто опечатка, но это еще один пример неправильной работы tldp.org. BashGuide или Bash Hackers Wiki - намного лучшие ссылки imho.
Джон Б
@JohnB Спасибо. Обе ссылки в закладки. Я исправил текст в ответе.
%%
или##
, так как это запоминающееся и достаточно редкое место, чтобы быстро найти нужный раздел.man bash
/##
#
находится сразу слева от$
, и%
сразу же справа. Мнемоника не нужна - просто посмотрите вниз. (Это, вероятно, по крайней мере, часть того, почему эти символы были выбраны.)Ответы:
Когда
%
используется в шаблоне,${variable%substring}
он будет возвращать содержимоеvariable
с кратчайшим вхождением,substring
удаленным из задней частиvariable
.Эта функция поддерживает шаблоны подстановочных знаков - поэтому она принимает звездочку (звездочку) в качестве замены для нуля или более символов.
Следует отметить, что это специфично для Bash - другие оболочки linux не обязательно содержат эту функцию.
Если вы хотите узнать больше о работе со строками в Bash, я настоятельно рекомендую прочитать эту страницу. Среди других полезных функций это, например, объясняет, что делает
%%
:)Изменить: Я забыл упомянуть , что , когда он используется в шаблоне
$((variable%number))
или персонаж будет функционировать в качестве оператора по модулю. DavidPostill имеет более конкретные ссылки на документацию в своем ответе.$((variable1%$variable2))
%
Когда
%
используется в другом контексте, он должен распознаваться только как обычный символ.источник
sh
-совместимой оболочке, а не только в Bash. (хотя, возможно, не вcsh
и тому подобное).%
используется, находится в спецификаторах формата дляprintf
.источник
Экспериментируя, я обнаружил, что совпадение после% отбрасывается, когда строка заключена в фигурные скобки (фигурные скобки).
Проиллюстрировать:
Вот вывод:
источник
В Linux shell (
bash
), что делает%
?В этом конкретном случае
%
это оператор сопоставления с образцом (обратите внимание, что он также может быть оператором по модулю ).Оператор сопоставления с образцом
Подстановка исходного параметра
Оператор по модулю
Операторы источника
источник
.*
и%
определяет, что это не жадный, тогда как%%
делает его жадным? Так что на самом деле в примере переименования не имеет значения, использовать%
или использовать (%%
ноmv "$file" "${file%.*png.jpg}.jpg"
обратите внимание на *), используя %%, переименуйте все файлы просто.jpg
, верно?$Pattern
» неверно, так как переменная$Pattern
не определена в примере, только текст «Шаблон» удаляется$var
при выполнении${var%Pattern}
или${var%%Pattern}
. Может быть, это просто опечатка, но это еще один пример неправильной работы tldp.org. BashGuide или Bash Hackers Wiki - намного лучшие ссылки imho.