Расширение параметров оболочки работает в ksh, но не в bash - PullRequest
0 голосов
/ 08 октября 2019

Почему следующий код выдает разные выходные данные в ksh и bash

p="folderA/folderB/folderC"
echo ${p%%+([^/])}
echo ${p#${p%%+([^/])}}

ksh:

folderA/folderB/
folderC

bash:

folderA/folderB/folderC

I 'Я особенно растерялся, потому что я использовал документацию bash для создания расширения этого параметра.

Я хочу извлечь имя папки после последней косой черты. Я нашел другой способ, который работает в ksh и bash:

echo ${p##*/}

, но я хотел бы понять, почему первый подход не работает.

Ответы [ 2 ]

1 голос
/ 09 октября 2019

Другая, более совместимая со стандартами оболочка Korn на самом деле выдает

folderA/folderB/folderC

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

В оболочке POSIX [^/] фактически не определено , нообычно (["^"/] более ясно) означает «либо ^, либо /», но вам может понадобиться «все, что не /», которое в глобальных оболочках POSIX равно [!/].

См. другой ответ для объяснения того, как GNU bash требуется shopt -s extglob для дополнительной поддержки совместимых с оболочкой Korn расширенных шаблонов глобализации.

1 голос
/ 08 октября 2019

+(...) - это расширенный синтаксис glob, вам нужно включить функцию extglob, чтобы bash понял это. И как указано в другом ответе , обычно окружность не должна использоваться для отрицания класса символов. Bash допускает эту ошибку, но в любом случае давайте используем правильный синтаксис для переносимости:

shopt -s extglob
p="folderA/folderB/folderC"
echo "${p%%+([!/])}"
echo "${p#${p%%+([!/])}}"

выход:

folderA/folderB/
folderC

Ссылка по теме: Справочное руководство Bash § Сопоставление с образцом.


Кстати, для этого вам не нужны расширенные глобусы.

p="folderA/folderB/folderC"
echo "${p%${p##*/}}"
echo "${p##*/}"

Вышеописанный скрипт работает так же хорошо в любой POSIX-совместимой оболочке.

...