3列に出力を印刷します


26
MYPATH=/var/www/html/error_logs/
TOTALFILE=$(ls $MYPATH* | wc -l)
FILETIME=$(stat --format=%y $MYPATH* | head -5 | cut -d'.' -f1)  
FILE=$(ls -1tcr $MYPATH* | head -5 | rev | cut -d/ -f1 | rev)
TOPLINE=$(head -1 $MYPATH* | grep -Po '".*?"' | head -5)

この5つのファイル情報をヘッダー付きの列にエレガントに印刷するにはどうすればよいですか?

FILE CREATED TIME   | FILE NAME        | ERROR HEADER
---------------------------------------------
$FILETIME           | $FILE            | $TOPLINE
2012-11-29 11:27:45 | 684939947465     | "SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)"

など5ファイル

total files: $TOTALFILE

私が欲しいものを手に入れる簡単な方法はありますか?

注:すべての変数をエコーすると、この出力が得られます

2012-11-29 11:27:45 2012-11-29 11:27:41 2012-11-28 23:33:01 2012-11-26 10:23:37 2012-11-19 22:49:36
684939947465 1313307654813 1311411049509 1234980770182 354797376843
"SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)" "SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)" "Connection to localhost:6379 failed: Connection refused (111)" "An error occurred connecting to Redis." "SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)"

あなたはあなたの質問に3つの答えを得ました。それらはすべてあなたが尋ねるものに対応しています。特定の答えを取得したい場合は、より正確にする必要があります。
ベルンハルト

回答:


25

そのためにシェルコマンド「column」を使用できますcolumn。MANページを確認してください

これをループと組み合わせると、ビジネスに参加できます。例:

#!/bin/sh

MYPATH=/
TOTALFILE=$(ls $MYPATH/* | wc -l)
FILE=$(ls -1tcr $MYPATH/* | head -5 | rev | cut -d/ -f1 | rev)

declare -a FILES
declare -a FILETIME

OUTPUT="FILENAME CREATED TIME ERROR_HEADER\n\n------------------------------ ----------------------------- ----------------------------------- ------$

for i in $MYPATH/*;
do
    FILES[${#FILES[@]}]="$i"
    FILETIME[${#FILETIME[@]}]=$(stat --format=%y $i | head -5 | cut -d'.' -f1)
    TOPLINE=$(head -1 $i | grep -Po '".*?"' | head -5)

    OUTPUT="$OUTPUT\n${FILES[${#FILES[@]}-1]} ${FILETIME[${#FILETIME[@]}-1]} $TOPLINE\n"
done

echo -ne $OUTPUT | column -t

どの列に何を入れるかをさらに制御する必要があったため、「*」で列を分割しsed 's/^/ \* \*/g'、最初の列から3番目の列にシフトするために何かを使用しました。私のために御treat走をしました。
LOAS

28

の使用をお勧めしますprintf。例:

printf "%-30s | %-30s | %-30s" "$FILETIME" "$FILE" "$TOPLINE"

where %-30s は、string型の入力引数に30文字を予約することを意味します。-意味は、アライメントを残しました。


2

私はAAループで行くだろう

printf " %-20s | %-20s | %-20s\n " FILE\ CREATED\ TIME FILE\ NAME ERROR\ HEAD
for i in "$MYPATH"/*
do
    printf "%-20s | %-20s | %-20s\n " $FILENAME $FILE $TOPLINE
done
printf "Total Files: %s" $TOTALFILES 

解決策ではない方法を紹介しました。ここで、FILENAME FILEおよびTOPLINEがループの前に実行されるのではなく、ループ内で処理されるようにコードを調整する必要があります。
BitsOfNix

すべての展開を引用する必要があります。引用しないと簡単に壊れてしまいます。
クリスダウン

2

unixの「貼り付け」でファイルを列に配置できるかどうかがわからない場合は、stdfoutを再フォーマットするためにprintfが必要になる場合があります。例:

カラム


3
U&Lへようこそ。テキストを画像として投稿しないでください。簡単にコピー/貼り付けできます。
アルケマール

1
同意します-コピーして貼り付けます。まだ投票できませんので、代わりにコメントして
ください-KolonUK

1

@qnimbusの回答はおそらくLinuxシステムに最適ですが、SunまたはIBMでは(2019年に使用することに不満がある場合は)このコマンドは使用できない場合があります。代わりに、prコマンドを使用して同じ効果を得ることができます。リンクされたページの例から、次を使用できます。

pr -3 word.lst | qprt

ファイルword.lstを3列で印刷します。とはいえ、これはあなたの問題の解決策の一部に過ぎず、残りは@qnimbusの回答に従うことにします。

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