Bashシェルスクリプトの出力の配置


29

私のスクリプト:

date
echo -e "${YELLOW}Network check${NC}\n\n"

while read hostname
do

ping -c 1 "$hostname" > /dev/null 2>&1 &&

echo -e "Network $hostname : ${GREEN}Online${NC}" ||
echo -e "${GRAY}Network $hostname${NC} : ${RED}Offline${NC}"

done < list.txt
        sleep 30
clear
done

次のような情報を出力しています:

Network 10.x.xx.xxx : Online   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.xxx : Offline   
Network 10.x.xx.x : Online   
Network 139.xxx.x.x : Online   
Network 208.xx.xxx.xxx : Online   
Network 193.xxx.xxx.x : Online

このようなものを取得するためにクリーンアップしたい:

Network 10.x.xx.xxx       : Online  
Network 10.x.xx.xxx       : Offline   
Network 10.x.xx.xxx       : Offline    
Network 10.x.xx.x         : Online    
Network 139.xxx.x.x       : Online  
Network 208.xx.xxx.xxx    : Online    
Network 193.xxx.xxx.x     : Online  
Network 193.xxx.xxx.xxx   : Offline

回答:


45

printf出力をフォーマットするために使用します(それよりechoポータブルです)。また、による拡張を必要とする形式で保存する代わりに、カラーエスケープシーケンスの実際の値を保存しますecho

RED=$(tput setaf 1) GREEN=$(tput setaf 2) YELLOW=$(tput setaf 3)
NC=$(tput sgr0) 
online="${GREEN}online$NC" offline="${RED}offline$NC"

ping -c 1 "$hostname" > /dev/null 2>&1 && state=$online || state=$offline
printf 'Network %-15s: %s\n' "$hostname" "$state"

%-15s(の文字数の長さとしてパッド右ようにスペースを含む文字列をそのフォーマット仕様であるzshfishし、他のほとんどのシェル/のprintfにバイト)は、少なくとも15であること。

$ printf '|%-4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcde|
 printf '|%4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcde|

切り捨てあり:

$ printf '|%.4s|\n' a ab abc abcd abcde
|a|
|ab|
|abc|
|abcd|
|abcd|
$ printf '|%4.4s|\n' a ab abc abcd abcde
|   a|
|  ab|
| abc|
|abcd|
|abcd|
$ printf '|%-4.4s|\n' a ab abc abcd abcde
|a   |
|ab  |
|abc |
|abcd|
|abcd|

列のテキストをフォーマットする他のユーティリティには、POSIXがexpand含まれます。

printf 'Network %s\t: %s\n' "$hostname" "$state" | expand -t 30

(ここでは\t、タブ文字でタブ文字()を30列ごとに展開します)

またはBSDcolumnまたはPOSIXpr

printf 'Network %s\n: %s\n' "$hostname" "$state" | pr -at2

(ここでは2つの36列幅の列に出力します(-wページ幅をデフォルトの72から変更するオプションを参照してください))。

またはBSDrs

{
   while...
      printf 'Network %s\n: %s\n' "$hostname" "$state"
   done
} | rs -e 0 2

columnすべての入力を読み取るまで出力を開始しないなど)。

またはGNUcolumns

printf 'Network %s\n: %s\n' "$hostname" "$state" | columns -w 25 -c 2

zshまた、文字列のパディングのためのいくつかのパラメータ展開フラグを持っています${(l:15:)hostname}ため、左パディングと${(r:15:)hostname}するために、右(切り捨てで)パディング。でプロンプト拡張(プロンプトまたはのようprint -Pでパラメータ展開で有効かなど%のフラグ)、それはまた、サポート%F{green}を行うことができますので、カラー出力のために:

online='%F{green}online%f'
printf '%s\n' "Network ${(r:15:)hostname}: ${(%)online}"

または:

print -rP "Network ${(r:15:)hostname}: $online"

のコンテンツ$hostnameもすぐに拡張される可能性$hostnameがありますが、コンテンツがあなたの制御下にない場合、コマンドインジェクションの脆弱性を構成します(などhostname='%<a[`reboot`]<'


35

単にcolumnコマンドで:

yourscript.sh | column -t

出力:

Network  10.x.xx.xxx     :  Online
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.xxx     :  Offline
Network  10.x.xx.x       :  Online
Network  139.xxx.x.x     :  Online
Network  208.xx.xxx.xxx  :  Online
Network  193.xxx.xxx.x   :  Online

愚かな質問には申し訳ありませんが、そのコマンドをどこに置くべきですか?
-pijaaa

@pijaaa、私の更新を参照して、スクリプト出力でパイプ
-RomanPerekhrest

10
column(BSDコマンド、Linuxに移植され、一部のディストリビューションではデフォルトで見つかり、GNUと混同しないようにcolumns)列ベースの幅を計算するために何かを出力する前に入力全体を読み取る必要があることに注意してください最も広いものに。
ステファンシャゼラス

3

スクリプトを更新\tして、列にタブアウトする場所(タブ)にセット番号を挿入します。

次のようなものを出力すると、必要なアライメントが得られます。

Network 10.x.xx.xxx\t: Online   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.xxx\t: Offline   
Network 10.x.xx.x\t: Online   
Network 139.xxx.x.x\t: Online   
Network 208.xx.xxx.xxx\t: Online   
Network 193.xxx.xxx.x\t: Online

3
これは、問題のスクリプトに基づいて簡単な例を追加する価値があるだろう...
スティーブン・キット

@StephenKitt ty Stephen、私はそれをたった1行以上にする方法を見つけようとしていましたが、これは正直私には起こりませんでした!
djsmiley2k-CoW

3
デフォルトのタブストップでは8列ごとにprintf 'Network %s\t: Online\n' 8.8.8.8 192.168.122.123適切に配置されないことに気付くでしょう。expand私の答えに示されているように、別のタブストップでタブを展開することでそれを回避できます。
ステファンシャゼラス

チェックマークアイコンをクリックして、これを回答として受け入れてください。
djsmiley2k-CoW

0

@Romanよりもさらに表示するには

yourscript.sh | column -t -s $'\t'

次に\t、各行を追加して列に分割します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.