Bash kabuk betiği çıktı hizalaması


29

Benim betiğim:

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

Bu şekilde bilgi çıktısı veriyor mu:

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

ki böyle bir şey elde etmek için temizlemek istiyorum:

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

Yanıtlar:


45

printfÇıktıyı formatlamak için kullanın (ayrıca daha taşınabilirecho ) Ayrıca renk kaçış dizilerinin gerçek değerini, onları genişletmeyi gerektiren bir biçimde depolamak yerine saklarım 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"

%-15sdizeleri sağdaki boşluklarla dolduran bir uzunluk belirtimidir (uzunluk zshve diğer birçok kabuğun / printf içindeki karakter sayısı fishve byte sayısı ) en az 15 olmalıdır.

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

Kesme ile:

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

Sütunlardaki metni biçimlendirmek için diğer yardımcı programlar POSIX'iexpand içerir :

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

(burada TAB karakterini genişletmek ( \t) her 30 sütunda bir sekme durağı var)

Veya BSDcolumn veya POSIXpr :

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

(burada 36 sütun genişliğinde 2 sütun üzerinde çıktı ( -wsayfa genişliğini varsayılan değer olarak değiştirme seçeneğine bakın ).

veya BSDrs :

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

(gibi columntüm girişleri okuyana kadar çıkış yapmaya başlamaz).

Veya GNUcolumns :

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

zsh: Ayrıca dize dolgu için bazı parametre genişletme bayraklar vardır ${(l:15:)hostname}için sol dolgu ve ${(r:15:)hostname}için doğru (kesikleri ile) dolgu. Bilgi istemi genişletme işleminde (istemlerde olduğu gibi veya bayrakla print -Pyapılan parametre genişlemelerinde etkinleştirildiği gibi %), %F{green}renk çıktısını da destekler , böylece şunları yapabilirsiniz:

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

Veya:

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

İçeriği sizin kontrolünüz altında değilse (içinde olduğu gibi ) $hostname, içeriği de derhal genişlemeye tabi tutulursa da, bu bir komut enjeksiyon güvenlik açığı oluşturur.$hostnamehostname='%<a[`reboot`]<'


35

Basitçe columnkomut ile:

yourscript.sh | column -t

Çıktı:

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

aptal soru için üzgünüm, ama bu komutu nereye koymalıyım?
pijaaa

@pijaaa, güncellememe bakın, senaryo çıktınızla
konuşun

10
Not column: (a BSD komutu, aynı zamanda Linux'a ve GNU karıştırılmamalıdır bazı dağılımlar, varsayılan olarak bulunan columnsbu esaslı sütunların genişliğini hesaplamak gerekiyor gibi bir şey çıkışı başlamadan önce tüm giriş okumak gerekir) en genişinde.
Stéphane Chazelas

3

Komut \tdizinizi, bir sütuna sekmek istediğiniz yere (sekmeler) ayarlamak için güncelleme .

Aşağıdakine benzer bir şey üretmek size gereken hizalamayı sağlar:

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


@StephenKitt ty Stephen, nasıl bir satırdan daha fazlasını yapabileceğimi anlamaya çalışıyordum ve dürüst olmak gerekirse başıma gelmedi!
djsmiley2k - CoW

3
Her 8 sütunun varsayılan sekme çubuklarıyla printf 'Network %s\t: Online\n' 8.8.8.8 192.168.122.123doğru şekilde hizalanmadığını fark edeceksiniz . Sen kullanarak bu geçici bir çözüm olabilir expandcevabım gösterildiği gibi farklı bir sekme durağı ile sekmeleri genişletmek için.
Stéphane Chazelas

Lütfen bunu cevap olarak kabul etmekten çekinmeyin, onay işaretini tıklatarak.
djsmiley2k - CoW,

0

@Roman'dan daha iyi görüntülemek için

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

Sonra \ther satıra sütuna bölmek için ekleyin .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.