답변:
보다 일반적인 솔루션으로 답변을 업데이트했습니다. 쉘 괄호 확장 만 사용하여 아래의 또 다른 대답을 참조하십시오 pritnf
.
$ str='Hello World!'
$ sed -r ':loop; s/ (=*):$/\1=:/; t loop' <<< "$(printf '%-20s:\n' "$str" )"
Hello World!========:
어떻게 작동합니까?
이것은 입력의 끝에 콜론이 뒤 따르는 (=*):$/
하나 이상의 공간을 캡처합니다 . 우리는 집합을 그룹으로 일치시키고 그 역 참조가 될 것입니다.=
:
=
\1
함께 :loop
우리 레이블라는 정의 loop
와 함께 t loop
그것은 그 라벨로 이동합니다 s/ (=*):$/\1=:/
성공적으로 대체를 수행하고있다;
로 대체되는 부분에서는 \1=:
항상 =
s 수를 늘리고 콜론 자체를 문자열 끝으로 되돌립니다.
filler='===================='
string='foo'
printf '%s\n' "$string${filler:${#string}}"
준다
foo=================
${#string}
값의 길이이고 $string
, 그리고 ${filler:${#string}}
의 문자열 인 $filler
오프셋으로부터 ${#string}
전방.
출력의 총 너비는 $filler
또는 최대 너비의 너비입니다 $string
.
를 사용하는 시스템에서 필러 문자열은 다음을 jot
사용하여 동적으로 만들 수 있습니다.
filler=$( jot -s '' -c 16 '=' '=' )
( =
한 줄 에 16 ). GNU 시스템은 다음을 사용할 수 있습니다 seq
.
filler=$( seq -s '=' 1 16 | tr -dc '=' )
다른 시스템은 Perl 또는 다른 빠른 방법으로 문자열을 동적으로 생성 할 수 있습니다.
printf
모든 시스템에서 거의 사용 가능한 필터를 생성하고 쉘과 같은 괄호 확장을 사용하지 bash/szh
않습니까?
printf
+ 중괄호 확장으로 bash
어떻게 하시겠습니까?
printf "%.20s:\n\n" "$str========================="
%.20s
문자열 잘림 형식은 어디에 있습니까?
그것을하는 한 가지 방법 :
printf "====================:\r%s\n\n" 'hello world!!'
====================\rhello world
됩니다. OP가 이것을 저장하고 화면에 인쇄하는 것이 아니라면 문제가 될 수 있습니다.
echo -e '=================\rHello World!!'
@terdon이 지적한 것과 같은 문제가 있습니다.
echo
지원하는 경우에만 -e
. 여러 가지 이유로 printf
거의 항상보다 낫습니다 echo
.
펄 접근 방식 :
$ perl -le '$k="hello world!!"; while(length($k)<20){$k.="=";} print "$k\n"'
hello world!!=======
또는 @SatoKatsura는 의견에서 지적했습니다.
perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'
UTF 멀티 바이트 문자를 지원해야하는 경우 다음을 사용하십시오.
PERL_UNICODE='AS' perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'
쉘에서 동일한 아이디어 :
v='hello world!!'; while [ ${#v} -lt 20 ]; do v="$v""="; done; printf '%s\n\n' "$v"
perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'
. 그러나 멀티 바이트 문자가 관련되면이 (및 지금까지 게시 된 다른 모든 솔루션)가 중단됩니다.
perl6
멀티 바이트 문자로도 올바르게 수행 할 수있는 방법이 있다고 생각 합니다. 그러나 반면 perl6
에 여러 가지면에서 성가신 일입니다.
PERL_UNICODE='AS'
. 예를 들어, 5 printf '%s' nóóös | perl -nle 'print length($_)'
를 printf '%s' nóóös | PERL_UNICODE='AS' perl -nle 'print length($_)'
인쇄 하는 동안 8을 인쇄합니다 ( "올바른").
또 다른 방법은 사용하고 printf
의해 첫 번째 문자 패딩 패턴을 명령 및 생성 Shell Brace Expansion
(당신은 넣을 수 있습니다 말을 수 ≥ 서식 영역 당신이 인쇄하려는와 {1..end}
)과의 모든 첫 번째 문자를 얻을 수 %.1s
있는 =
유일한 처음 20 문자 길이를 인쇄 한 후 s와 그 지역 %.20s
. 이것은 문자 / 단어를 복제하지 않고 반복하는 더 좋은 방법입니다.
printf '%.20s:\n' "$str$(printf '%.1s' ={1..20})"
Hello World!!=======:
설명 :
일반적으로 Brace Expansion 으로 {1..20}
인쇄하면 쉘 이 다음과 같이 확장 됩니다.
printf '%s ' {1..20}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
그것에 등호를 추가하면 ={1..20}
쉘은 다음과 같이 확장됩니다.
printf '%s ' ={1..20}
=1 =2 =3 =4 =5 =6 =7 =8 =9 =10 =11 =12 =13 =14 =15 =16 =17 =18 =19 =20
그리고 printf '%.1s'
이것이 실제로 의미하는 것은 printf '%WIDE.LENGTH'
, 기본 너비 로 위의 길이 중 하나만 인쇄하는 것 입니다. 결과는 20 회만 반복됩니다.1
=
이제 printf '%.20s:\n'
우리는 20 길이의 길이 만 인쇄 $str
하고 길이가 $str
<20이면 나머지는 =
공백 대신 채워지 는 생성에서 가져옵니다 .