변수 대체에 명령 대체를 중첩시킬 수 있습니까?


10

명령을 통해 액세스하는 특정 문자열에 변수 대체를 사용하고 싶습니다. 예를 들어 클립 보드에 무언가를 복사하면 다음과 같이 액세스 할 수 있습니다.

$ xclip -o -selection clipboard
Here's a string I just copied.

변수에 변수를 할당하면 변수를 대체 할 수 있습니다.

$ var=$(xclip -o -selection clipboard)
$ echo $var
Here's a string I just copied.
$ echo ${var/copi/knott}
Here's a string I just knotted.

그러나 변수에 변수를 할당하지 않고 변수 대체를 수행하는 방법이 있습니까? 개념적으로 이와 같은 것.

$ echo ${$(xclip -o -selection clipboard)/copi/knott}
bash: ${$(xclip -o -selection clipboard)/copi/knott}: bad substitution

이 구문 var은 문자열이 아니라 변수 이름이어야 하므로 실패 합니다.

답변:


6

아냐, 못해 bash대부분의 다른 쉘 (제외 zsh)은 중첩 된 대체를 허용하지 않습니다.

을 사용하면 중첩 대체를zsh 수행 할 수 있습니다 .

$ echo ${$(echo 123)/123/456}   
456

이 답변은에 불가능하다는 정황 증거를 제공하므로이 답변을 수락하겠습니다 bash. (그리고 나에게 다시 이주로 나아 간다 zsh.)
Sparhawk

2

네, 그렇게 할 수 있습니다. 정말 예쁘지 않습니다. 중첩보다 인라인 과 비슷 합니다. 문제는 확장 한 매개 변수의 값을 조작해야한다는 것입니다. 해당 매개 변수에 값이 없으면 별다른 조치를 취하지 않아도됩니다. 따라서 값 확장 하면서 할당 할 수 있으며 바로 가기가 아닙니다.

v=; echo "${v:=${0##*["$0${v:=$(xsel -bo)}"]}${v/copi/knott}}"

$0체인 내 에서 param 확장을 사용하여 과제 를 숨 깁니다 . 중첩 된 할당 확장 내에서 var의 값을 할당합니다. 바깥 쪽이 우선합니다. 그러나 안쪽 쪽이 말한대로 확장되기 때문입니다. 그러나 내부 확장을 끄면 원하는 것을 얻을 수 있습니다. 내 클립 보드에 문자열을 복사 한 후 (나는이 없습니다 xclip- 단지 xsel) 는 인쇄 :

Here's a string I just knotted.

$0그래도 나가면 무슨 일이 일어나고 있는지 좀 더 명확합니다 .

v=; echo "${v:=${v:=$(xsel -bo)}${v/copi/knott}}"

인쇄 :

Here's a string I just copied.  Here's a string I just knotted.

내부 할당이 수정 전에 발생하기 때문에, 외부 할당이 우선하며 내부 할당의 확장 수정 된 내부 확장으로 확장됩니다.

물론 대상 매개 변수가 이미 할당 된 경우 그중 아무것도 작동하지 않습니다. 따라서 처음에 변수를 비우면 확실하게 수행 할 수 있습니다 ... 솔직히 말하면 아마도 가장 편리한 시간입니다. .


당신이 말한 것처럼 변수를 할당하는 것보다 더 나쁜 해결 방법 일지라도 해결 방법으로 +1입니다!
Sparhawk

@Sparhawk-예, 확실히 더 나쁩니다. 그리고 어쨌든 아무런 문제가 없습니다. 불확실성을 제외하고는 얻을 것이 없습니다. alias좀 더 편리하게하기 위해 약간의 간접 지시를 내릴 수 있지만 그 가치가 있다면 안전 인용을 처리 eval하고 어쨌든 같은 것을 수행하는 기능을 설정해야 합니다. w / eval-명령 하위 출력의 첫 문자를 실행 가능한 확장 구문으로 만들 수 있다면 훨씬 더 쉽게 얻을 수 있습니다. 나는 그런 일이 쉬울 것이라는 것을 알고 있습니다 xsel-stdin이 필요합니다 xsel.
mikeserv

@Sparhawk-어떤 경우에는 프롬프트 또는 here-doc 확장과 같이 유용 할 수 있기 때문에 현재 쉘 할당을 얻을 수 없기 때문에 그 중 하나를 수행하는 방법 만 알고 있습니다.
mikeserv

1

변수를 만들지 않으려면 문자열 대체를 수행하는 다른 방법이 있습니다.

$ echo $(xclip -o -selection clipboard | sed 's/copi/knott/')
Here's a string I just knotted.

고마워, 나는 sed대신 사용할 수 있다는 것을 알고 있었지만 대체의 중첩에 관한 일반적인 질문에 더 가깝습니다.
Sparhawk

@Sparhawk 내 지식으로는 변수가 없으면 변수 대체를 수행 할 수 없습니다.
John1024

그래, 아마 그 대답 일 것입니다. 다른 사람이 참조 된 답변이 있는지 확인하기 위해 며칠 동안 질문을 열어두고 그렇지 않은 경우이 질문을 수락합니다. 감사.
Sparhawk

@Sparhawk 아주 좋아.
John1024

+1이지만 bash에서 작동하지 않는다는 좀 더 구체적인 상황 증거를 제공하기 때문에 다른 대답 을 받아 들일 것 입니다.
Sparhawk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.