
중첩된 매개변수 확장을 처리할 때 다음 중 사물을 참조하는 올바른 방법은 무엇입니까?
이것:
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"
패턴 문자를 포함 할 수 있습니다 . 마찬가지로 $var
in에 "${var#"${var%%[![:space:]]*}"}"
패턴 문자(*?[)가 포함될 수 있고 이를 패턴으로 해석하지 않으려면 확장명을 다음과 같이 인용하십시오.
"${var#"${var%%[![:space:]]*}"}"
변수 할당의 오른쪽 부분은 인용된 것으로 간주되며 인용문은 필요하지 않습니다(그러나 손상되지는 않음). 두 가지 모두에도 해당됩니다.
var=${var#"${var%%[![:space:]]*}"}
strip_ext=${filename%."$filename_ext"}