Bash에서 배열 확장을 위해 다중 문자 구분 기호를 사용하는 방법은 무엇입니까?

Bash에서 배열 확장을 위해 다중 문자 구분 기호를 사용하는 방법은 무엇입니까?

나는 문제를 가장 간단한 경우로 축소했습니다. 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%bC 및 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.

관련 정보