Bash - ${##}를 사용하여 명령 결과에서 하위 문자열을 제거할 수 있습니까?

Bash - ${##}를 사용하여 명령 결과에서 하위 문자열을 제거할 수 있습니까?

나는 이것이 나에게 git의 현재 브랜치의 이름을 줄 것이라고 생각합니다.

echo "${`git symbolic-ref HEAD`##refs/heads}"

그러나 이로 인해

-bash: ${`git symbolic-ref HEAD`##refs/heads}: bad substitution

결과를 중간 변수에 저장하지 않고 한 줄 명령 결과에 ##을 사용할 수 있습니까? 아니면 다른 방법(예: ?)을 사용해야 합니까 sed?

답변1

아니요 bash. 하지만 다음을 수행할 수 있습니다 zsh.

printf '%s\n' "${$(git symbolic-ref HEAD)#refs/heads}"

거기에서 일할 것입니다.

또는 언제든지 다음을 사용하여 스트리핑을 수행할 수 있습니다 sed.

printf '%s\n' "$(git symbolic-ref HEAD | sed '1s|^refs/heads||')"

삭제할 부분에 개행 문자가 포함되어 있으면 상황은 더욱 복잡해집니다. 예를 들어, 제거하려는 부분이 이면 $'1\n2\n3\n'다음과 같은 것이 필요합니다.

cmd1 -- "$(cmd2 | sed '1{$!N;$!N;$!N; s/^1\n2\n3\n//;}')"

cmd2따라서 종료 상태를 유지하는 이점이 있는 임시 변수를 사용할 수도 있습니다 .

strip=$'1\n2\n3\n'

out=$(cmd2); cmd2_status=$?
cmd1 -- "${out#"$strip"}"

답변2

아니요, 유감스럽게도 이 ##관용구는 다음에 속하기 때문에 불가능합니다.바꾸다확장만 가능하므로 항상 기존 변수를 참조해야 합니다.

그러나 귀하의 경우에는 다음 팁이 마음에 드실 것입니다.

sh -c 'echo "${*##refs/heads}"' - "`git symbolic-ref HEAD`"

또는: (더 나은 바시즘으로서)

sh -c 'echo "${*##refs/heads}"' -- "$(git symbolic-ref HEAD)"

sh이는 명령 출력을 인수로 사용하여 비대화형 명령을 실행한 다음 git 해당 인수에 ##관용구를 사용합니다.

명령의 출력이 충분히 삭제되었다고 신뢰할 수 있는 경우(예: *또는 기타 와일드카드가 포함되지 않음) 큰따옴표를 입력하는 시간을 절약할 수 있습니다.

관련 정보