중첩된 매개변수 확장을 참조하는 올바른 방법은 무엇입니까?

중첩된 매개변수 확장을 참조하는 올바른 방법은 무엇입니까?

중첩된 매개변수 확장을 처리할 때 다음 중 사물을 참조하는 올바른 방법은 무엇입니까?

이것:

var="${var#"${var%%[![:space:]]*}"}"

아니면 이거:

var="${var#${var%%[![:space:]]*}}"

나는 그것이 두 가지 방법으로 이루어지는 것을 보았습니다. 첫 번째 변형은스택 오버플로 답변. 이것은 이 질문에 대한 가장 높은 지지를 받은 답변 중 하나입니다(질문은 변수에서 공백을 자르는 방법에 관한 것입니다).


또한 리터럴 텍스트의 "단어"나 "패턴"이 아닌 변수를 사용할 때 사물을 참조하는 방법을 다루는 평판 좋은 소스를 찾는 데 어려움을 겪고 있습니다. 다음 두 항목 중 올바른 것은 무엇입니까?

이것:

strip_ext="${filename%."$filename_ext"}"

아니면 이거:

strip_ext="${filename%.$filename_ext}"

답변1

전개의 우변을 어떻게 해석하고 싶은가에 달려 있는 것 같습니다. 패턴 또는 리터럴 문자열로.

여기서 인용되지 않은 *패턴은 전체 문자열을 먹습니다. 인용문에는 문자 그대로 별표가 제거되었습니다.

var='foo*'
echo ":${var%%*}:"                 # this prints ::
echo ":${var%%"*"}:"               # this prints :foo:

패턴을 변수에 넣으면 효과는 동일합니다.

var='foo*'
pat='*'
echo ":${var%%$pat}:"              # this prints ::
echo ":${var%%"$pat"}:"            # this prints :foo:

또는 오른쪽의 다른 매개변수로 확장합니다.

var='foo*'
pat='x*x'
echo ":${var%%${pat//x}}:"         # this prints ::
echo ":${var%%"${pat//x}"}:"       # this prints :foo:

( ${pat//x}결과는 *이번에도 마찬가지다.)

내가 시도한 모든 POSIX 유사 쉘(Bash, ksh, yash)은 동일한 동작을 얻습니다. 물론 Zsh는 다르며 오른쪽의 모든 매개변수 확장은 단어 분할 문제에서와 마찬가지로 Zsh에서 참조됩니다. 확장 프로그램에서 이를 변경하는 데 사용할 수 있는 연산자가 있다고 생각합니다.

답변2

두 경우 모두 일반적으로 첫 번째 방법이 원하는 것입니다. 오른쪽 문자열을 ${var#*a}따옴표로 묶지 않으면 패턴으로 해석/확장됩니다. 이 예에서는 선행 텍스트가 첫 번째 문자까지 제거됩니다 a. 인용된 경우: ${var#"*a"}확장 프로그램이 텍스트를 제거합니다 *a. 다음과 같은 경우 문제가 될 수 있습니다.

"${filename%."$filename_ext"}"

"$filename_ext"패턴 문자를 포함 할 수 있습니다 . 마찬가지로 $varin에 "${var#"${var%%[![:space:]]*}"}"패턴 문자(*?[)가 포함될 수 있고 이를 패턴으로 해석하지 않으려면 확장명을 다음과 같이 인용하십시오.

"${var#"${var%%[![:space:]]*}"}"

변수 할당의 오른쪽 부분은 인용된 것으로 간주되며 인용문은 필요하지 않습니다(그러나 손상되지는 않음). 두 가지 모두에도 해당됩니다.

      var=${var#"${var%%[![:space:]]*}"}
strip_ext=${filename%."$filename_ext"}

관련 정보