พิมพ์เอาต์พุตไปยัง 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)"

คุณมีสามคำตอบสำหรับคำถามของคุณซึ่งทั้งหมดตอบสนองสิ่งที่คุณถาม คุณควรแม่นยำมากขึ้นในสิ่งที่คุณต้องการรับคำตอบเฉพาะ
แบร์นฮาร์ด

คำตอบ:


25

คุณสามารถใช้คำสั่งเชลล์คอลัมน์ '' การที่ตรวจสอบ: หน้าคนcolumn

รวมสิ่งนี้เข้ากับลูปและคุณอยู่ในธุรกิจเช่น:

#!/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'เพื่อเปลี่ยนสิ่งต่าง ๆ จากคอลัมน์แรกเป็นคอลัมน์ที่สาม ทำงานรักษาสำหรับฉัน
LOAS

28

ฉันอยากจะแนะนำให้ใช้printfเช่น:

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

ในกรณีที่%-30s หมายถึงการสำรอง 30 ตัวอักษรสำหรับอาร์กิวเมนต์ใส่ของประเภทสตริง -หมายถึงการจัดตำแหน่งซ้าย


2

ฉันจะไปกับวงเอ

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

คุณต้องอ้างการขยายทั้งหมดของคุณไม่เช่นนั้นจะแตกง่าย
Chris Down

2

ไม่แน่ใจว่านี่คือสิ่งที่คุณทำอยู่ "วาง" ในยูนิกซ์สามารถจัดเรียงไฟล์ในคอลัมน์คุณอาจต้อง printf เพื่อฟอร์แมต sttdout ตัวอย่าง:

คอลัมน์


3
ยินดีต้อนรับสู่ U&L โปรดอย่าโพสต์ข้อความเป็นรูปภาพคุณสามารถคัดลอก / วางได้อย่างง่ายดาย
Archemar

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.