回答:
より一般的なソリューションになるように回答を更新しました。また、参照して以下の私の別の答えだけのシェルブレース展開を使用するとpritnf。
$ str='Hello World!'
$ sed -r ':loop; s/ (=*):$/\1=:/; t loop' <<< "$(printf '%-20s:\n' "$str" )"
Hello World!========:
使い方?
これは、入力の最後にコロンが続く(=*):$/1つ以上のスペースを1つキャプチャします。のセットをグループ一致として作成し、その後方参照になります。=:=\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ますか?
それを行う1つの方法:
printf "====================:\r%s\n\n" 'hello world!!'
====================\rhello world。これは、OPが画面に印刷するだけでなく、これを保存する必要がある場合に問題になる可能性があります。
echo -e '=================\rHello World!!'、@terdonが指摘したのと同じ問題があります。
echoサポートされて-eいる場合のみ。 多くの理由により、printfほとんどの場合、よりも優れechoています。
Perlのアプローチ:
$ 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'。たとえば、printf '%s' nóóös | perl -nle 'print length($_)'8(「間違った」)をprintf '%s' nóóös | PERL_UNICODE='AS' perl -nle 'print length($_)'印刷し、5(「正しい」)を印刷します。
もう一つの方法は、のみ使用しているprintfことで、コマンドと最初の文字のパディングパターンを生成するShell Brace Expansionあなたが置くことができます(最後のあなたが印刷する数≥フォーマットするエリアとを{1..end})、その最初の文字で%.1sある=s のみを取得し、最初の20文字の長さのみを印刷しますそのエリア%.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'、我々は一つだけ印刷されているLENGTHデフォルトで上記のそれらのを1 WIDE。結果は=sのみで、20回繰り返されます。
これでprintf '%.20s:\n'、20の長さのみを印刷$strし、長さが$str20未満の場合、残りは生成された=sから取得し、スペースではなく埋めます。