
README.md
저는 a 를 $1\n
밑줄 길이로 채우는 빠른 bash 함수를 작성하려고 합니다 $1
.
다른 stackexchange 질문에서 찾은 코드에는 문자 <n>
시간을 인쇄하려면 다음을 사용한다고 나와 있습니다.
printf '=%.0s' {1..<n>}
실제로 이것은 작동합니다(분명히 <n>
숫자를 대신 사용함).
광산을 만들려면 README.md
함수가 다음과 같을 것이라고 생각했습니다.
make_readme() {
echo "$1
$(printf '=%.0s' {1..${#1}})" > README.md
}
make_readme "Some project"
그러나 이렇게 하면 다음 텍스트가 포함된 파일이 생성됩니다.
Some project
=
내가 아는 한, ${#1}
in은 $(...)
빈 문자열로 대체됩니다. 내 생각엔 명령 대체에는 고유한 매개변수 범위가 있고 매개변수가 대체에 전달되지 않으므로 $1
아무것도 대체되지 않는 것 같습니다.
마침내 몇 가지 해결 방법을 찾았습니다.
make_readme() {
underline="printf '=%.0s' {1..${#1}}"
echo "$1
$(eval "$underline")" > README.md
}
또는
make_readme() {
echo "$1" > README.md
printf '=%.0s' {1..${#1}} >> README.md
}
하지만 이 작업을 한 줄로 수행할 수 있는 방법이 있어야 할 것 같습니다.
답변1
제안:
#!/bin/bash
make_readme () {
printf '%s\n%s\n' "$1" "$( eval "printf '=%.0s' {1..${#1}}" )"
}
make_readme 'Hello World!' >README.md
또는 외부 유틸리티 호출이 작동하는 경우
#!/bin/bash
make_readme () {
# print $1, then replace all characters in it with = and print again
sed 'p; s/./=/g' <<<"$1"
}
make_readme 'Hello World!' >README.md
둘 다 README.md
include라는 파일을 생성합니다.
Hello World!
============
답변2
나는 다음을 추천한다:
make_readme () {
printf '%s\n%s\n' "$1" "${1//?/=}"
}
make_readme 'Hello World!' >README.md
답변3
당신을 위한실제적인 문제이것은 "주어진 문자열을 생성합니다.동일한 길이= 문자열 수정된 다른 답변에 동의합니다.끈bash, zsh, tr, sed 등을 사용하십시오.
하지만 당신을 위해서명시된 문제이는 "주어진숫자해당 길이의 문자열을 생성합니다.", 귀하의 방법이 작동하지 않는 이유는 bash가 다음을 포함하는 "매개변수 확장"을 수행하기 때문입니다.${#1}
뒤쪽에지원 확장 참조;쉘 확장에 따른 매뉴얼 또는 정보.
당신을 위한 몇 가지 방법이 있습니다할 수 있는주어진 길이의 문자열을 생성합니다:
- 당신의
%.0s
기술을 사용하되프로그램seq
중괄호 확장 대신(명령 대체가 먼저 실행되는 하위 쉘을 생성하고 매개변수 확장을 수행하기 때문에):
printf '%s\n' "$1"; printf '=%.0s' $( seq ${#1} ); printf '\n'
- "가변 너비" 형식을 사용하여 패딩을 생성한
printf
후 수정합니다.
# create a string of spaces equal to length of $1, then convert spaces to =
t=$(printf '%*s' ${#1} ''); printf '%s\n' "$1" "${t// /=}"
# create a string of zeros equal to length of $1, then convert zeros to =
t=$(printf '%0*d' ${#1} 0); printf '%s\n' "$1" "${t//0/=}"
- 오늘날의 시스템에서는 일반적이지만 POSIX에서는 일반적이지 않은 Perl 사용:
printf '%s\n' "$1" "$( perl -e "print '='x${#1}" )"
# quoting $(perl...) isn't needed when we know (all) the chars are =
# but is good practice in general
# note I reverse the more common method of singlequoting a perl script
# with internal strings doublequoted, because I _want_ shell expansion
답변4
bash
쉘을 사용할 필요가 없으면 zsh
대신 다음을 수행하십시오.
make_readme() printf '%s\n' $1 ${(l[$#1][=])}
왼쪽 패딩 매개변수 확장 플래그는 어디에 있습니까 (l[length][string])
(여기에서는 매개변수가 전혀 적용되지 않습니다).
각 문자의 표시 너비가 고려되므로 너비가 0이거나 너비가 2개인 문자가 포함된 텍스트에 더 잘 작동합니다.
$ make_readme() printf '%s\n' $1 ${(l[$#1*3-${#${(ml:$#1*2:)1}}][=])}
$ make_readme $'Ste\u0301phane'
Stéphane
========
$ make_readme 'FOOBAR'
FOOBAR
============
(이것은 U+FF21..U+FF3A 이중 너비 영문자입니다. 브라우저에서는 이를 전체 이중 너비로 표시하지 않을 수 있지만 터미널에서는 표시되어야 합니다.)
${(ml:width:)1}
패딩은 $1
각 width
문자의 표시 너비를 고려하므로 문자 수의 두 배로 패딩할 때 $1
문자 수 와 문자 수 $1
를 비교하여 표시 너비를 계산할 수 있습니다. 바라보다문자열의 표시 너비를 가져옵니다.더 알아보기.