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

how can i elegantly print this out 5 files information into columns with headers?

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

and so on 5 files

total files: $TOTALFILE

is there any easy way to get what i want?

note: this output i got when echo every 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)"
1
  • You got three answers to your question, which all address the things you ask. You should be much more precise in what you want to get a specific answer. – Bernhard Dec 24 '12 at 12:13
31

You can use the column command which on Linux is part of the util-linux package. It's also available on FreeBSD, NetBSD, OpenBSD and DragonFly BSD.

Combine this with a loop and you're in business, e.g.:

#!/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
2
  • I needed further control of what went in which column, so I split columns on '*' and used something like sed 's/^/ \* \*/g' for shifting things from first column into third. Worked a treat for me. – LOAS Nov 16 '16 at 16:03
  • I think there are some typos in the script because it doesn't work. Is it perhaps a missing double quote "? – Cristian Ciupitu Jan 16 at 17:15
38

I would recommend using printf, e.g.:

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

Where %-30s means to reserve 30 characters for the input argument of type string. The - denotes left alignment.

0
2

I would go with a a loop

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
  • I gave you the how not the solution. Now you need to adapt your code so that the FILENAME FILE and TOPLINE are taken care inside of the loop instead of doing it before the loop. – BitsOfNix Dec 23 '12 at 17:22
  • You need to quote all of your expansions, or this will easily break. – Chris Down Dec 23 '12 at 20:17
2

Not sure if this is what are you up to, "paste" in unix can arrange files in column, you may need printf to reformat the sttdout. example:

column

2
  • 4
    welcomme to U&L, please do not post text as image, you can copy/paste easyly. – Archemar May 3 '17 at 5:17
  • 1
    I agree - copy and paste. I can't vote down yet, so comment instead – KolonUK Oct 23 '18 at 11:24
2

@qnimbus answer is probably best for Linux systems but on Sun or IBM (if you're un/lucky enough to be using one in 2019) this command may not be available. Instead you could use the pr command to get the same effect. From the examples on the linked page you can use the following:

pr -3 word.lst | qprt

to print the file word.lst in 3 columns. That said, this is only a part of a solution to your problem and for the rest I defer to @qnimbus answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.