명령을 통해 액세스되는 특정 문자열에 대해 변수 대체를 사용하고 싶습니다. 예를 들어 클립보드에 복사한 내용을 다음과 같이 접근할 수 있습니다.
$ 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
문자열이 아닌 변수 이름이 필요하기 때문에 이 구문은 실패합니다 .
답변1
답변2
예, 그렇게 할 수 있습니다. 정말 예쁘지 않아요. 그것은 더 비슷하다대기줄중첩된 것보다. 문제는 확장된 매개변수의 값을 조작해야 한다는 것입니다. 매개변수에 값이 없으면 많은 작업을 수행할 수 없습니다. 따라서 값을 할당할 수 있습니다.하지만확장하면 지름길이 아닙니다.
v=; echo "${v:=${0##*["$0${v:=$(xsel -bo)}"]}${v/copi/knott}}"
$0
체인 내에서 매개변수 확장을 사용하여숨다분배하다. 중첩 할당 확장 내에서 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.
...내부 할당은 수정 전에 발생하기 때문에 위에서 언급한 것처럼 외부 할당이 우선하며 내부 할당의 확장까지 확장됩니다.그리고내부 확장을 수정했습니다.
물론, 타겟 매개변수가이미할당 - 따라서 변수를 먼저 지운 경우에만 이 작업을 수행할 수 있습니다. 솔직히 할당하기에 가장 편리한 시간일 것입니다.
답변3
다음은 연결된 매개변수 대체를 위해 임시 변수 할당을 우회하는 해킹의 예입니다.
declare -a values=( "4: " "#1" "#2" "#3" "#4" )
declare -A arr["VALUES"]="${values[@]}"
echo -e "Original: ${arr[@]}"
"${arr[@]#*: ?}" >&/dev/null; san="${_//#/}"
echo -e "Sanitized: $san"
설명하다:
arr
array 의 값으로 연관 배열을 초기화 합니다 values
. 첫 번째 요소에는 값 요소의 수, :
필터링해야 하는 ; 및 #
모든 값의 접두사가 포함됩니다.
"${arr[@]#*: ?}" >&/dev/null
이는 값을 먼저 확장하고 ( ) arr
까지 이전의 모든 항목을 필터링하여 합계 결과를 삭제하는 매개변수 대체입니다 . 이는 결과 변수 할당 누락으로 인해 발생하는 오류도 억제합니다.'4: '
#*: ?
stdout
stderr
>&
출력 ( )을 ( ) 에 할당 하고 둘 다에 할당 2>&1
하는 약어입니다 .stderr
fd2
stdout
fd1
/dev/null
이제 비결은 bash의 특수 밑줄 _
인수를 사용하여 이전 명령(위의 첫 번째 인수 확장 작업 및 결과 리디렉션 /dev/null
)에서 버려진 결과 인수를 두 번째 인수 대체에 복사하는 것입니다. 여기서 #
접두사 값이 필터링됩니다.
san="${_//#/}"
산출:
원본: 4: #1#2#3#4
소독 : 1 2 3 4
또한보십시오:특수 매개변수 및 쉘 변수
답변4
Linux에서는 소스 명령을 파이프할 수 있습니다.
echo $(xclip -o -selection clipboard)/copi/knott|source /dev/stdin
그렇지 않은 시스템의 경우 /dev/stdin
먼저 임시 파일에 쓴 다음 해당 파일에 써야 합니다 source
.