Bash 스크립트의 printf 공백 문자

Bash 스크립트의 printf 공백 문자

현재 Cygwin 클라이언트에서 실행 중인 스크립트의 목적을 위해 printf에서 공백 문자를 어떻게 이스케이프합니까? 공백이 포함된 줄(명령줄에서 다음과 같이 작동함)$SPC를 에코합니다.) 예

SPC=$(printf \\$(printf '%03o' 32))

이유가 궁금하실 경우를 대비해 이 코드에서는 Bash 4+에 의존하지 않도록 연관 배열을 시뮬레이션하려고 합니다... 이론적으로 거의 모든 bash 환경에서 실행할 수 있는 일반적인 예가 되기를 바랍니다. .

전체 스크립트는 다음과 같습니다.

#!/bin/bash

DEFAULT_INDEX=""
LAST_INDEX=0
SPC=$(printf \\$(printf '%03o' 32))

# MICROSOFT OUTLOOK VERSIONS.
OUTLOOKS=( "Cancel^Do$SPCnot$SPCtry$SPCto$SPCsend$SPCmessage$SPCvia$SPCOutlook"
           "URL^Just$SPCthe$SPCmailto$SPCURL"
           "Outlook$SPC2003^C:\Program$SPCFiles\Microsoft$SPCOffice\Office12"
           "Outlook$SPC2007^C:\Program$SPCFiles\Microsoft$SPCOffice\Office12"
           "Outlook$SPC2010^C:\Program$SPCFiles\Microsoft$SPCOffice\Office14" )

# ITERATES THROUGH ARRAY AND MAKES NUMBERED SELECTION LIST.
printOutlooksArraySelectionList() {
    LIST_TITLE="MICROSOFT OUTLOOK SELECTION LIST"
    echo
    printf "\t\t\E[37;1;44m%-0s %s %s %s\033[0m" $LIST_TITLE
    echo
    echo
    DEFAULT_VALUE="Outlook 2010"
    index=0
    for i in "${OUTLOOKS[@]}"; do
        key=${i%%^*}
        value=${i##*^}
        if [ "$key" == "$DEFAULT_KEY" ]; then
            DEFAULT_INDEX=$index
    fi
            printf "\t\E[37;44m%-3s %-13s\033[0m \E[1;34;40m%-41s\033[0m\n" \
                   $index $key $value
            echo
            ((index++))
    done
    # SETS LAST_INDEX TO INDEX VALUE OF LAST ITEM IN ARRAY.
    ((LAST_INDEX = index - 1))
}

printOutlooksArraySelectionList

출력은 다음과 같을 것으로 예상됩니다.

            MICROSOFT OUTLOOK SELECTION LIST

    0   Cancel        Do not try to send message via Outlook

    1   URL           Just the mailto URL

    2   Outlook 2003  C:\Program Files\Microsoft Office\Office12

    3   Outlook 2007  C:\Program Files\Microsoft Office\Office12

    4   Outlook 2010  C:\Program Files\Microsoft Office\Office14

이 문제를 해결하기 위해 결국 printf를 사용하지 않고 다음과 같이 했습니다.

echo -e "\t\E[37;44m${index}\t${key}\033[0m\t\t\E[1;34;40m${value}\033[0m"

이 스크립트는 내 목적에 충분합니다.

답변1

나는 당신이 무엇을 하고 싶은지 이해하지 못합니다. 귀하의 코드는 SPC단일 문자가 공백인 길이 1의 문자열을 설정합니다 . 이는 매우 정교한 접근 방식입니다. SPC=" "똑같이 효과적이고 이해하기 쉽습니다.

나는 당신의 전체 스크립트를 검토하지 않았지만 나중에 뭔가 잘못된 것을 발견했습니다. 당신은 다음과 같은 것을 썼습니다 . 이것은 변수 , 가 아직 정의되지 않았기 때문에 "URL^Just$SPCthe$SPCmailto$SPCURL"문자열을 생성합니다 . 변수 확장 뒤에 변수 이름의 일부일 수 있는 문자가 오는 경우 다음이 필요합니다.URL^Just$SPCthe$SPCmailto$SPCURL변수 이름의 끝을 나타냅니다., 예를 들어 이름을 중괄호 안에 입력합니다 URL^Just${SPC}the${SPC}mailto${SPC}URL. 그런데 왜 글을 쓰지 않았는지 이해가 안 돼요 "URL^Just the mailto URL".

작은 해시 테이블을 인코딩하려면 두 개의 배열을 사용하는 것이 좋습니다. 하나는 키용이고 다른 하나는 값용입니다. 이렇게 하면 인코딩에 대해 걱정하지 않고 임의의 문자열을 저장할 수 있습니다. 다음은 검색 및 추가에 대한 개요입니다( 연습을 위해 keys및 배열의 ​​이름을 values인수로 남겨두기).

lookup () { # $1=key; set value to the value found
  for ((i=1; i<=${#keys}; i++)); do
    if [[ ${keys[$i]} = $1 ]]; then value=${values[$i]}; return 0; fi
  done
  unset value; return 1
}
add () { # $1=key $2=value
  for ((i=1; i<=${#keys}; i++)); do
    if [[ ${keys[$i]} = $1 ]]; then values[$i]=$2; return; fi
  done
  keys[$i]=$1; values[$i]=$2
}

보다 효율적인 접근 방식은 각 항목을 쉘 변수에 저장하는 것입니다. 예를 들어 테이블이 에 foo매핑 되면 변수가 설정됩니다 . 키를 영숫자로 인코딩해야 하는데 이는 간단하지 않습니다(한 가지 방법은 sha1을 사용하여 키를 해시하고 키를 에 저장 하고 값을 에 저장하는 것입니다 ). 테이블의 키를 열거해야 하는 경우 목록을 별도로 저장해야 합니다.somekeysomevaluetable_foo_somekey=somevaluetable_foo_${sha1_of_somekey}_keytable_foo_${sha1_of_somekey}_key

또는 단순한 셸의 기능 이상의 기능이 필요할 때 더 강력한 도구를 사용할 수 있습니다. Ksh93(pdksh 아님), bash 4 및 zsh에는 모두 연관 배열이 있습니다. 그 외에도 Perl과 Python 및 기타 언어가 있습니다.

답변2

  • 이미 문자열 주위에 따옴표를 사용하고 있으므로 $SPC문자열에 따옴표가 필요하지 않습니다.이익이 없다. 당신은 필요하지 않습니다어느정의공간거기.

  • ~처럼자일스문자열에 like "URL^Just$SPCthe$SPCmailto$SPCURL"존재하지 않는 변수가 포함되어 있음을 나타냅니다. 변수는 어떤 변수 이름에도 사용할 수 없는 문자로 끝나거나 {}as 로 (올바르게) 구분된 경우에 사용 됩니다 ${key}.

답변3

나는 이미 이 문제에 대해 몇 가지 오해를 언급했습니다. 하지만 어쨌든.

공백이 포함된 줄(명령줄에서 echo $SPC로 작동함)은 다음과 같습니다.

SPC=$(printf \\$(printf '%03o' 32))

실제로 줄에는 공백이 없습니다. 그것은 확장된다

printf \\040

확장으로 인해 좋은 것은 없습니다. printf출력을 하는 printf것은 전혀 좋은 생각이 아닙니다.

원하는 경우 인쇄에 공백 기호가 표시될 수 있습니다.

$> printf '  %03o\n' 32
  040

선행 Null 및 선행 0:

$> printf "%010o\n" 32
0000000040

$> printf "% 10o\n" 32
        40

UPD댓글로:

$> printf '\\%03o\n' 32
\040

관련 정보