echo または print で複数の行を揃える方法

echo または print で複数の行を揃える方法

マウントされたファイル システムを fstab にリストされているエントリと照合するスクリプトがありますが、ここで直面している問題は、出力を揃えておくことです。

以下はスクリプトの出力です。

/  is mounted OK
/boot  is mounted OK
/was8  is mounted OK
/was8/slogs  is mounted OK
/was8/cluster  is mounted OK
/was8/working  is mounted OK
/was8/app  is mounted OK
/was8/tools  is mounted OK
/was8/plugin  is mounted OK
/was8/coreproduct  is mounted OK
...

これらの線を揃えて、次のようになるようにします。

/  is mounted                       OK
/boot  is mounted                   OK
/was8  is mounted                   OK
/was8/slogs  is mounted             OK
/was8/cluster  is mounted           OK
/was8/working  is mounted           OK
/was8/app  is mounted               OK
/was8/tools  is mounted             OK
/was8/plugin  is mounted            OK
/was8/coreproduct  is mounted       OK
...

column と xargs を試しましたが、望みどおりの結果は得られませんでした。誰か助けてくれませんか。

答え1

一般に、印刷を行う場合、書式文字列の幅を に設定できますprintf。は、オーバーフローしない限り、%-20sフィールドに 20 文字(*)%-20.20s幅の文字列を印刷します。 は、20 文字にして、オーバーフローした部分を削除します。

(※ただし、例えばBashはprintf実際にはカウントされますバイトäUTF-8などの文字では違いが見られます。

例えば

printf "%-40s %s\n" "$mountpoint  is mounted" "$status"

最初の部分は(少なくとも)40文字幅になります。

/was8/coreproduct  is mounted            OK
...

あるいは、そのような入力を後処理する必要がある場合は、Perl または awk を使用できます。

perl -pe 's/(.*) +(\S+)$/ sprintf "%-40s %s", $1, $2 /e'  < file

awk '{s=$NF; sub(/ *[^ ]+ *$/, "", $0); printf "%-40s %s\n", $0, s}'  < file

どちらも基本的に最後の空白以外の文字列を分離し、最初の部分と共に 2 つの部分を固定幅フィールドに出力します。


あるいは、フィールド間の区切りをそのまま維持することにこだわらない場合は、@ がコメントしたより簡単な解決策があります。ジョアンだろう:

awk '{s=$NF; NF-- ; printf "%-40s %s\n", $0, s}' < file

これにより、以下の出力が生成されます。前の 2 つのスペースが 1 つに縮小されていることに注意してください。これは、 またはいずれかのフィールドが変更されたときにが全体を再構築するis mountedために発生します。awk$0NF

/was8/coreproduct is mounted             OK

答え2

Perl を少し難読化します:

perl -ne 'printf "%-40s %s", /(.*) (.*)/s'

答え3

1 つの方法は、ステータス コードの前にタブを導入することです。例:

<input rev | sed 's/ /\t/' | rev | column -s $'\t' -t

出力:

/  is mounted                        OK
/boot  is mounted                    OK
/was8  is mounted                    OK
/was8/slogs  is mounted              OK
/was8/cluster  is mounted            OK
/was8/working  is mounted            OK
/was8/app  is mounted                OK
/was8/tools  is mounted              OK
/was8/plugin  is mounted             OK
/was8/coreproduct  is mounted        OK
/was8/ihs  is mounted                OK
/was8/backup  is mounted             OK
/was8/ihs/logs  is mounted           OK
/was8/wsdm  is mounted               OK
/was8/ws  is mounted                 OK
/was8/ihs/logs/analysis  is mounted  OK

答え4

これも、列ユーティリティを使用すると非常に簡単に実行できます。重要なのは、「列」の間に何らかの区別マーカーを含めることです。たとえば、スペースが区別マーカーである場合は、column -s ' ' -o ' ' -tスペースに完全に揃えられます。

私はこれを頻繁に使用しており、コードを整列させるためにこれを利用する優れた vim マクロもいくつか作成しました。必要な一般的な構文は次のとおりです。

column -s <Separator String> -o <Separator String in Output> -t

これはタブベースの回答の一般化ですが、必ずしもタブの挿入を必要としません。

関連情報