\u2263
両側に2つのスペースで区切られたUnicode文字を使用して、bash関数の最初の2つの引数を印刷したいと思います。問題は、最終的なUnicodeを70列に表示する必要があることです。文字範囲が列68に$1
達すると、$2
追加の文字が切り捨てられます。
1 2 3 V 4 5 6 7
1234567890123456789012345678901234567890123456789012345678901234567890
U FIRST-ARG SECOND-ARG U
U FIRST-ARG-LONGGGGGGGGGGGGGGGG SECOND-ARG U
可能な最大幅で列番号(34
文字で説明されている選択など)を指定できます。V
FIRST-ARG
開始されたcl
合計の最大長cr
。
local cl=34 cr=30
printf ' \u2263 %.${cl}s %.${cr}s \u2263\n' "$1" "$2"
答え1
は空白で埋められ、63に切り捨てられますbash
。printf
%-63.63s
バイト文字ではないため、すべての文字がシングルバイトでない限り、書式設定/並べ替えには使用できません。 99.99%の文字は、複数のバイトを使用してUTF-8でエンコードされています。 U + 2263文字はUTF-8の場合は3バイト、GB18030の場合は4バイトでエンコードされています。
ksh93と同様に、bash${var:offset:length}
は文字レベルでコピーされますが、すべての文字が単一幅の場合にのみ機能します。
テキストを正しく整列させるには、次のような方法があります。
- 文字の表示幅を考慮したパディング/切り捨て演算子を使用してください。
- 出力が端末に到達すると仮定し、制御シーケンスを使用して書き込み位置に目的のものを書き込み、そうでないものを削除するように端末に指示します。
1の場合、bashの代わりに組み込み演算子(ksh93やzshなど)を持つシェルを使用できます。
zshから:
align() printf ' \u2263 %s \u2263\n' ${(j[ ]mr[63])@}
引数r[length]
拡張フラグ(ここでは空白r[length][ ]
がデフォルトのパディング文字に省略されています)r
ightは指定された長さで埋められ、m
表示幅の単位の長さとともに使用されます。
または、後述のように、左揃え(および右パディング)と右揃え$1
です。$2
align() printf ' \u2263 %s \u2263\n' "${(mr[31])1} ${(ml[31])2}"
これを使用すると、ksh93
より簡単になります。
align() printf ' \u2263 %-63.63Ls \u2263\n' "$1 $2"
%Ls
これとは対照的に、バイトでは%s
なく文字列を使用して、表示幅に応じて文字列を埋め、切り取ります。
または左$1
と右を揃えます$2
。
align() printf ' \u2263 %-31.31Ls %31.31Ls \u2263\n' "$1" "$2"
入力に制御文字が含まれていると機能しません。
2の場合は、自動マージンを無効にして全文を書き、68列に移動して" ≣"
残りを書き込んで消去できます。
am_off=$(tput rmam) am_on=$(tput smam)
col68=$(tput cr; tput cuf 68)
del_to_eol=$(tput el)
align() {
printf ' \u2263 %s\u2263%s\n' "$am_off$1 $2$col68 " "$del_to_eol$am_on"
}
答え2
2つの長いパラメータを取得します。
set -- '123456789.123456789.123456789.123456789.' '987654321.987654321.987654321.987654321.'
Vを40に設定すると、field1には40文字、field2には68-40 = 28文字があります。
cl=40
cr=$((68-cl))
今、私たちは最初のフィールドを左揃えし、2番目のフィールドを右揃えで印刷しようとします(長い引数では見えませんが)。 printf形式の文字列でフィールドの幅を設定するだけでは不十分で、パラメータの部分文字列のみを取得する必要があります。
printf '\u2263 %-*s%*s \u2263\n' "$cl" "${1:0:cl}" "$cr" "${2:0:cr}"
≣ 123456789.123456789.123456789.123456789.987654321.987654321.98765432 ≣
私たちはそれを見ることができます
- "123456789.123456789.123456789.123456789."、最初のパラメーターの最初の40文字
- "987654321.987654321.98765432"、2番目の最初の28文字です。
答え3
ああ?何が必要ですか?
問題が文字列の長さを操作する方法である場合は、ここで説明されている文字列関数を使用できます。 https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion
フォーマットされた方法で何かを印刷する必要がある場合は、Cとまったく同じフォーマットをprintf
使用echo
してください。printf()
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-printf