ksh
첫 번째 인수를 화면에 인쇄하고 -
적절한 수의 문자에 밑줄을 긋는 다음 함수를 작성했습니다 .
print_underlined () {
word=$1
echo $word
i=${#word}
while [[ i -gt 0 ]]; do
printf "-"
(( i = $i - 1 ))
done
printf "\n"
}
예:
$ print_underlined foobar
foobar
------
$
밑줄 친 단어를 화면에 표시하는 더 간단하고 우아한 방법이 있는지 궁금합니다.
기록을 위해 다음을 사용하고 있습니다.
- 솔라리스 10
- 크쉬 88
답변1
문제의 핵심은 기존 문자열과 길이가 동일한 밑줄로만 구성된 문자열을 구성하는 것입니다. 최신 버전 의 bash, ksh 또는 zsh에서는 다음 구문을 사용하여 이 문자열을 작성할 수 있습니다 ${VARIABLE//PATTERN/REPLACEMENT}
. underlines=${word//?/_}
그러나 이 구성은 ksh88에는 존재하지 않습니다.
모든 쉘에서 사용할 수 있습니다 tr
. POSIX 호환 구현을 사용하면 tr
다음을 작성할 수 있습니다.
underlines=$(printf %s "$word" | tr -c '_' '[_*]')
저는 Solaris 10이 기본적으로 POSIX와 호환된다고 생각 tr
하지만, 레거시 구현이 있을 수도 있습니다(이전 Solaris 버전과 호환 가능). 의 역사적 구현은 구문을 tr
이해하지 못할 수도 있지만 [x*]
다음 구문(POSIX에서는 보장되지 않음)을 허용하는 경향이 있습니다. 이는 "개행 문자가 아닌 모든 항목을 "로 바꾸십시오 _
"를 의미합니다.
underlines=$(echo "$word" | tr -c '\010' '_')
underlines=${underlines%_}
다음은 루프나 외부 프로그램을 사용하지 않고 Bourne 쉘에서 작동하는 약간 미친 방법입니다(적어도 도입 이후 set -f
- 빈 디렉토리에서 실행하면 부족함이 완화되지만 set -f
). 안타깝게도 문자열에 공백이 포함되어 있지 않은 경우에만 작동합니다.
set -f # turn off globbing
IFS=$word # split at any character in $word
set a $word # split $word into one word between each character, i.e. empty words
shift # remove the leading a (needed in case $word starts with -)
IFS=_
underlines=$* # join the empty words, separated with the new value of $IFS
더 복잡한 변형은 공백을 처리하지만 연속된 공백 시퀀스가 없는 경우에만 해당됩니다. 공백 문자 시퀀스는 IFS
항상 축소되므로 이 트릭을 더 이상 사용할 수 없을 것 같습니다 .
set -f
unset IFS; set a $0 # split at whitespace
IFS=$*; set $* # split into empty words
IFS=_; underlines=$* # collect the empty
답변2
최신 쉘에서는 다음을 수행할 수 있습니다 printf %s\\n "${word//?/-}"
. 나는 ksh88에 특별한 확장자가 없다고 생각합니다.
추가 프로세스가 마음에 들지 않으면 이렇게 할 수 있습니다 printf %s\\n "${word}" | sed -e 's/./-/g'
.
귀하의 접근 방식도 훌륭하지만 다음과 같이 약간 변경하겠습니다.
print_underlined () {
word=$1
printf %s\\n "$word"
i=${#word}
while (( i )); do
printf -
(( i = i - 1 ))
done
echo
}
완전히 다른 접근 방식을 사용하려면 터미널의 기능을 사용하여 실제 밑줄을 표시하십시오(사용 가능한 경우).
tput smul; printf %s\\n "$word"; tput rmul
물론 이는 스크립트가 실행 중인 터미널이 이를 지원하는지 아는 경우에만 작동합니다.
답변3
나는 단지 인터넷 검색으로 이것을 찾았습니다.
underline() { echo $1; echo "${1//?/${2:--}}";}
기본적으로는 동일하지만 더 컴팩트합니다. 혼란스럽다면 버팀대 교체에 대한 자세한 정보를 찾아보세요.여기. sed 구문과 매우 유사합니다.
답변4
이는 Solaris 10 및 ksh88에서 작동하는 POSIX 호환 방식입니다.
print_underlined () {
printf "%s\n%s\n" "$1" $(printf "%s\n" "$1" | sed "s/./-/g")
}
$ print_underlined "hello world"
hello world
-----------