![Bash에서 배열 확장을 위해 다중 문자 구분 기호를 사용하는 방법은 무엇입니까?](https://linux55.com/image/74868/Bash%EC%97%90%EC%84%9C%20%EB%B0%B0%EC%97%B4%20%ED%99%95%EC%9E%A5%EC%9D%84%20%EC%9C%84%ED%95%B4%20%EB%8B%A4%EC%A4%91%20%EB%AC%B8%EC%9E%90%20%EA%B5%AC%EB%B6%84%20%EA%B8%B0%ED%98%B8%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
나는 문제를 가장 간단한 경우로 축소했습니다. myscript.sh
다음 내용이 포함된 스크립트 가 있다고 가정해 보겠습니다 .
#!/bin/bash
IFS='%20'
echo "$*"
다음과 같이 명령을 실행하면 출력은 다음과 같습니다.
me@myhost ~ $ ./myscript.sh fee fi fo fum
fee%fi%fo%fum
이는 bash
매뉴얼 페이지에 명시된 대로 예상되는 동작입니다.
* Expands to the positional parameters, starting from one. When
the expansion occurs within double quotes, it expands to a sin-
gle word with the value of each parameter separated by the first
character of the IFS special variable. That is, "$*" is equiva-
lent to "$1c$2c...", where c is the first character of the value
of the IFS variable. If IFS is unset, the parameters are sepa-
rated by spaces. If IFS is null, the parameters are joined
without intervening separators.
그러나 내가 얻고 싶은 것은 출력입니다.
fee%20fi%20fo%20fum
따라서 단일 문자 대신 여러 문자 구분 기호 필드를 사용하십시오.
이를 수행할 수 있는 방법이 있습니까 bash
?
고쳐 쓰다:
아래 mikeserv의 데이터와 다음 기사를 기반으로 합니다.왜 printf가 echo보다 나은가요?, 나는 다음을 수행하게 되었습니다(위의 예에 표시된 것처럼 다시 가장 간단한 경우로 단순화되었습니다).
#!/bin/bash
word="$1"
shift
if [ "$#" -gt 0 ] ; then
word="$word$(printf '%%20%s' "$@")"
fi
printf '%s\n' "$word"
unset word
답변1
printf
출력에서 그 뒤에 오는 각 인수에 해당 형식 문자열을 적용합니다. 이는 bash
인수 목록에 구분 기호 문자열을 적용하는 데 사용할 수 있는 쉘 내장 함수 입니다 .
예를 들어:
printf %s:delimit: arg1 arg2 arg3
arg1:delimit:arg2:delimit:arg3:delimit:
문제는, printf
아니멈추다인수 끝에 형식 문자열을 적용하므로 마지막 인수에는 구분 기호가 추가됩니다. 어떤 경우에는 다음과 같이 할 수 있습니다.
printf %b:delimit: \\0150 \\0145 \\0171\\c
h:delimit:e:delimit:y
printf
%b
C 및 8진수 이스케이프는 일부 형식이 있고 특정 지점에서 출력을 출력하는 형식을 갖는 ytes %b
로 해석됩니다 \c
. 따라서 printf
위의 y 뒤에는 :delimit:
문자열이 오지 않습니다. 해당 형식 문자열은 그렇지 않으면 표시로 끝나기 때문입니다.
따라서 각 매개변수를 문자 그대로 해석하고 싶다면그리고후행 구분 기호가 없으면 매개변수 목록 자체를 처리해야 합니다.
set -- arg1 arg2 arg3
for arg do shift
set -- "$@" :delimit: "$arg"
done; shift
printf %s "$@"
arg1:delimit:arg2:delimit:arg3
답변2
당신 은 zsh
사용할 수 있습니다j:string:
매개변수 확장 플래그:
set -- fee fi fo fum
delims=%20
print -rl ${(j:$delims:)@}
답변3
사용 중이 bash
거나 변수 확장이 활성화된 다른 셸을 사용 중이고 인수 내부에 공백이 없는 경우 다음을 수행할 수 있습니다.
#!/bin/bash
line=$*
echo "${line// /:delimiter:}"
IFS
공백의 경우 before before 변수를 설정하여 다른 필드 구분 기호를 사용해야 합니다 line
.