2017-02-14 12 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 

bar을 반환 target1b을 얻을 수있는 방법이

존재?

떠들썩한 파티에서 탭 완성을 수행, $1 종종 input1 또는 input2 변화에 같은 CLI에 입력 할 수 나는 변화 중 하나를 입력 할 때 bar을 반환 basename 대신 globbing을 사용할 수 있도록하고 싶습니다.

+1

'$ 도움이 경우, 하나의 순수한 글로브의 {입력을 ## * /}'사용하지 않습니다 정규식. (그것은 glob이다) –

답변

2

basename은 외부 유틸리티를 실행하는 데 필요한 하위 프로세스를 생성하는 오버 헤드를 피하기를 원한다고 가정합니다.

그렇다면 배시의 정규식 매칭 연산자 =~ 사용 다음은, 할 수

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

정규식 ([^/]+)/?$ 포착 마지막 ($) 경로 성분 ([^/]+)을하는 / 후행 제외한 경우 선물 (/?).

정규식 일치 연산의 결과는 을 사용할 때마다 Bash가 채우는 특수 배열 변수 ${BASH_REMATCH[@]}에 저장됩니다. 경로 구성 요소 일치 하위 표현식 일치 무엇
는 (항상 전체 경기를 포함 요소 0)으로 인해 일반적으로 캡처 그룹라고 (...) 안에 1 (여기 만 해당) 표현식을 되 고, 요소 1로 사용할 수 있습니다.

+1

시원한. Did not '는 $ {BASH_REMATCH [@]}에 대해 알고 있습니다. 감사합니다. – Bleakley

2

내가 (! 의미가) 이미 mklement0's answer 허용 볼 수 있지만, 여기 다른 사람   —

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