2017-02-14 5 views
1
input1="/$HOME/Desktop/foo/bar/" 
input2="/$HOME/Desktop/foo/bar" 
target1a=$(basename "$input1") 
target1b="${input1##*/}" 
target2a=$(basename "$input2") 
target2b="${input2##*/}" 

echo $target1a 
echo $target1b 
echo $target2a 
echo $target2b 

возвращаетполучать с глобированием базовым, когда задним/присутствуют

bar 

bar 
bar 

есть способ, чтобы получить target1b также вернуть bar?

ли до завершения вкладки в Баш, $1 часто могут быть введены в кли, как в input1 или input2 вариаций, и я хотел бы иметь возможность использовать подстановку вместо basename вернуться bar когда либо изменение вводится.

+1

'$ {входные ## * /}' не использует регулярное выражение вообще. (Это глобус) –

ответ

2

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

Если это так, то следующее, в котором используется регулярное выражение сопоставления оператора в Bash, =~, может сделать:

[[ $input1 =~ ([^/]+)/?$ ]] && target1b=${BASH_REMATCH[1]} 

Regex ([^/]+)/?$ захватить последний ($) компонент пути ([^/]+), за исключением завершающая /, если данный (/?).

Результаты операции, связанной с регулярным выражением, хранятся в специальной переменной массива ${BASH_REMATCH[@]}, которую Bash заполняет после каждого использования =~.
Что путь-компонент сопоставления подвыражения соответствует доступен в качестве элемента 1, из-за того 1-й (и здесь только) подвыражения, заключенный в (...), обычно называемую группу с захвата (элемент 0 всегда содержит общий матч).

+1

классный. Не знал о '$ {BASH_REMATCH [@]}' Спасибо – Bleakley

2

Я вижу, ты уже принял mklement0's answer (имеет смысл!), Но вот один чистый Глоб, в случае, если это помогает кому-либо еще   —

target1b="${input1%/}"  # Strip the trailing slash, if any 
target1b="${target1b##*/}" # Now drop the leading directory components