การจัดตำแหน่งสคริปต์ Bash shell


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เป็นข้อกำหนดคุณสมบัติการจัดรูปแบบที่วางสตริงด้วยช่องว่างทางด้านขวาเพื่อให้ความยาว (ในจำนวนตัวอักษรในzshและfishและไบต์ใน shells / 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|

ยูทิลิตี้อื่น ๆ เพื่อจัดรูปแบบข้อความในคอลัมน์รวมถึงPOSIXexpand :

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

(ที่นี่ขยายอักขระ TAB ( \t) พร้อมกับแท็บหยุดทุก ๆ 30 คอลัมน์)

หรือBSDcolumnหรือPOSIXpr :

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

(ที่นี่จะแสดงผลในคอลัมน์กว้าง 36 36 คอลัมน์ 2 ตัว (ดู-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) จะต้องอ่านอินพุตทั้งหมดก่อนที่จะสามารถเริ่มส่งออกบางสิ่งบางอย่างตามที่จำเป็นในการคำนวณความกว้างของคอลัมน์ตาม ที่กว้างที่สุด
Stéphane Chazelas

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
มันจะคุ้มค่าที่จะเพิ่มตัวอย่างสั้น ๆ ตามสคริปต์ในคำถาม ...
Stephen Kitt

@StephenKitt ty Stephen ฉันพยายามหาวิธีที่จะทำให้มันเป็นมากกว่าหนึ่งบรรทัดและสิ่งนี้โดยสุจริตไม่ได้เกิดขึ้นกับฉัน!
djsmiley2k - CoW

3
คุณจะสังเกตเห็นว่าแท็บเริ่มต้นทุก 8 คอลัมน์printf 'Network %s\t: Online\n' 8.8.8.8 192.168.122.123ไม่ได้จัดแนวอย่างเหมาะสม คุณสามารถแก้ไขได้โดยใช้expandเพื่อขยายแท็บด้วยการหยุดแท็บอื่นตามที่แสดงในคำตอบของฉัน
Stéphane Chazelas

โปรดอย่าลังเลที่จะยอมรับสิ่งนี้เป็นคำตอบแล้วโดยคลิกที่ไอคอนเห็บ
djsmiley2k - CoW

0

เพื่อแสดงดีกว่า @Roman

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

จากนั้นเพิ่ม\tในแต่ละบรรทัดเพื่อแยกออกเป็นคอลัมน์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.