web-dev-qa-db-fra.com

imprimer la sortie sur 3 colonnes séparées

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)

comment puis-je imprimer élégamment ces informations de 5 fichiers dans des colonnes avec des en-têtes?

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)"

et ainsi de suite 5 fichiers

total files: $TOTALFILE

existe-t-il un moyen facile d'obtenir ce que je veux?

note: cette sortie que j'ai obtenue en faisant écho à chaque variable

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)"
30
ADM

Vous pouvez utiliser la commande Shell 'colonne' pour cela, vérifiez: column MAN page .

Combinez cela avec une boucle et vous êtes en affaires, par exemple:

#!/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
28
QNimbus

Je recommanderais d'utiliser printf, par exemple:

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

%-30s signifie réserver 30 caractères pour l'argument d'entrée de type chaîne. Le - indique l'alignement à gauche.

31
Bernhard

J'irais avec une boucle

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 
2
BitsOfNix

Je ne sais pas si c'est ce que vous faites, "coller" dans unix peut organiser les fichiers dans la colonne, vous devrez peut-être printf pour reformater le sttdout. exemple:

 column 

2
Them Huyen

La réponse @qnimbus est probablement la meilleure pour les systèmes Linux mais sur Sun ou IBM (si vous n'êtes pas assez chanceux pour en utiliser un en 2019) cette commande peut ne pas être disponible. À la place, vous pouvez utiliser la commande pr pour obtenir le même effet. À partir des exemples de la page liée, vous pouvez utiliser les éléments suivants:

pr -3 Word.lst | qprt

pour imprimer le fichier Word.lst en 3 colonnes. Cela dit, ce n'est qu'une partie d'une solution à votre problème et pour le reste je m'en remets à la réponse @qnimbus.

1
nonsensickle