현재 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을 사용하여 키를 해시하고 키를 에 저장 하고 값을 에 저장하는 것입니다 ). 테이블의 키를 열거해야 하는 경우 목록을 별도로 저장해야 합니다.somekey
somevalue
table_foo_somekey=somevalue
table_foo_${sha1_of_somekey}_key
table_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