Liên kết đầu ra shell Bash


29

Kịch bản của tôi:

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

Đang xuất thông tin như thế này:

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

mà tôi muốn dọn dẹp để có được thứ gì đó như thế này:

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

Câu trả lời:


45

Sử dụng printfđể định dạng đầu ra (nó cũng dễ mang theo hơnecho ). Tôi cũng sẽ lưu trữ giá trị thực của các chuỗi thoát màu thay vì lưu trữ chúng ở dạng yêu cầu mở rộng bằng 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"

%-15slà một đặc điểm kỹ thuật định dạng mà miếng đệm các dây với không gian bên phải như vậy là chiều dài (trong số ký tự trong zshfishbyte trong hầu hết các tiện ích khác / printf ) phải có ít nhất 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|

Với sự cắt ngắn:

$ 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|

Các tiện ích khác để định dạng văn bản trong các cột bao gồm POSIXexpand :

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

(ở đây mở rộng ký tự TAB ( \t) với tab dừng sau mỗi 30 cột)

Hoặc BSDcolumn hoặc POSIXpr :

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

(ở đây xuất ra 2 cột rộng 36 cột (xem -wtùy chọn thay đổi độ rộng trang từ mặc định là 72)).

hoặc BSDrs :

{
   while...
      printf 'Network %s\n: %s\n' "$hostname" "$state"
   done
} | rs -e 0 2

(giống như columnsẽ không bắt đầu xuất cho đến khi nó đã đọc tất cả các đầu vào).

Hoặc GNUcolumns :

printf 'Network %s\n: %s\n' "$hostname" "$state" | columns -w 25 -c 2

zshcũng có một số cờ mở rộng tham số cho chuỗi padding: ${(l:15:)hostname}cho trái padding và ${(r:15:)hostname}cho đúng đệm (với cắt ngắn). Trong mở rộng nhanh chóng (như trong lời nhắc hoặc trong print -Phoặc như được bật trong mở rộng tham số với %cờ), nó cũng hỗ trợ %F{green}cho đầu ra màu, vì vậy bạn có thể làm:

online='%F{green}online%f'
printf '%s\n' "Network ${(r:15:)hostname}: ${(%)online}"

Hoặc là:

print -rP "Network ${(r:15:)hostname}: $online"

Mặc dù nội dung $hostnamesau đó cũng sẽ bị mở rộng nhanh chóng, điều này sẽ tạo thành lỗ hổng tiêm lệnh nếu nội dung $hostnamekhông nằm trong tầm kiểm soát của bạn (như trong hostname='%<a[`reboot`]<')


35

Đơn giản chỉ với columnlệnh:

yourscript.sh | column -t

Đầu ra:

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

Tôi xin lỗi vì câu hỏi ngu ngốc, nhưng tôi nên đặt lệnh đó ở đâu?
pijaaa

@pijaaa, xem bản cập nhật của tôi, kết hợp với đầu ra tập lệnh của bạn
RomanPerekhrest

10
Lưu ý rằng column(một lệnh BSD, cũng được chuyển sang Linux và được tìm thấy theo mặc định trên một số bản phân phối, không bị nhầm lẫn với GNU columns) sẽ cần phải đọc toàn bộ đầu vào trước khi có thể bắt đầu xuất một cái gì đó vì nó cần tính toán độ rộng của các cột dựa trên trên cái rộng nhất
Stéphane Chazelas

3

Cập nhật tập lệnh của bạn để chèn một số được đặt vào \t(các tab) nơi bạn muốn tab ra một cột.

Xuất ra một cái gì đó tương tự như sau sẽ cung cấp cho bạn sự liên kết cần thiế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
Sẽ đáng để thêm một ví dụ ngắn dựa trên kịch bản trong câu hỏi ...
Stephen Kitt

@StephenKitt ty Stephen, tôi đã cố gắng tìm ra cách làm cho nó không chỉ là một dòng, và điều này thực sự không xảy ra với tôi!
djsmiley2k - CoW

3
Bạn sẽ nhận thấy rằng với các tab mặc định cứ sau 8 cột, printf 'Network %s\t: Online\n' 8.8.8.8 192.168.122.123sẽ không căn chỉnh chính xác. Bạn có thể giải quyết vấn đề đó bằng cách sử dụng expandđể mở rộng các tab bằng một điểm dừng tab khác như thể hiện trong câu trả lời của tôi.
Stéphane Chazelas

Xin vui lòng chấp nhận đây là câu trả lời sau đó, bằng cách nhấp vào biểu tượng đánh dấu.
djsmiley2k - CoW

0

Để hiển thị thậm chí còn tốt hơn @Roman

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

Sau đó thêm \tvào từng dòng để chia nó thành cột.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.