Вирівнювання вихідного сценарію оболонки Bash


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й байти в більшості інших оболонок / 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

(Тут висновок на 2-36 стовпців шириною стовпців (див -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), повинна буде прочитати весь вхід, перш ніж він може почати щось виводити, як це потрібно для обчислення ширини стовпців на основі на найширшому.
Стефан Шазелас

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
Варто було б додати короткий приклад на основі сценарію у питанні ...
Стівен Кітт

@StephenKitt ty Стівен, я намагався зрозуміти, як зробити це більше, ніж один рядок, і це, чесно кажучи, не трапилось мені!
djsmiley2k - CoW

3
Ви помітите, що кожні 8 стовпців за стовпцями за замовчуванням printf 'Network %s\t: Online\n' 8.8.8.8 192.168.122.123не вирівнюються належним чином. Ви могли б обійти це за допомогою expandрозширення вкладок з іншою зупинкою вкладки, як показано в моїй відповіді.
Стефан Шазелас

Будь ласка, не соромтеся прийняти це як відповідь тоді, натиснувши значок галочки.
djsmiley2k - Корова

0

Відображати навіть краще, ніж @Roman

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

Потім додайте \tв кожен рядок, щоб розділити його на стовпчик.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.