बैश शैल स्क्रिप्ट आउटपुट संरेखण


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

(यहाँ टैब वर्ण का विस्तार \t) टैब के साथ हर 30 कॉलम को रोकता है)

या BSDcolumn या POSIXpr :

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

(यहां 2 36-कॉलम चौड़े कॉलम पर आउटपुट करना ( -wपृष्ठ चौड़ाई को 72 के डिफ़ॉल्ट से बदलने का विकल्प देखें )।

या बीएसडीrs :

{
   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

बेवकूफ सवाल के लिए खेद है, लेकिन मैं उस आदेश को कहां रखूं?
पिजाअ

@ पिजा, मेरा अपडेट देखें, अपने स्क्रिप्ट आउटपुट के साथ पाइप
रोमनप्रेचर

10
ध्यान दें कि column(बीएसडी कमांड, जिसे लिनक्स में भी पोर्ट किया गया है और कुछ वितरणों पर डिफ़ॉल्ट रूप से पाया जाता है, जीएनयू के साथ भ्रमित नहीं होना चाहिए columns) पूरे इनपुट को पढ़ने से पहले इसे कुछ आउटपुट करना शुरू करना होगा क्योंकि इसमें कॉलम की चौड़ाई की गणना करना आवश्यक है सबसे चौड़े पर।
स्टीफन चेज़लस

3

अपनी स्क्रिप्ट को एक सेट संख्या \t(टैब) में सम्मिलित करने के लिए अपडेट करें जहाँ आप एक कॉलम से टैब करना चाहते हैं।

निम्नलिखित के लिए कुछ simular आउटपुट आपको आवश्यक संरेखण देगा:

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 -

3
आप देखेंगे कि हर 8 कॉलम में डिफ़ॉल्ट टैबस्टॉप के साथ, printf 'Network %s\t: Online\n' 8.8.8.8 192.168.122.123ठीक से संरेखित नहीं किया गया है। आप expandअपने जवाब में दिखाए गए अनुसार टैब को अलग टैब स्टॉप के साथ विस्तारित करके उपयोग कर सकते हैं ।
स्टीफन चेज़लस

कृपया टिक आइकन पर क्लिक करके इसे उत्तर के रूप में स्वीकार करने के लिए स्वतंत्र महसूस करें।
djsmiley2k - COW

0

@ रमन से भी बेहतर प्रदर्शित करने के लिए

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

फिर \tप्रत्येक पंक्ति में जोड़कर इसे कॉलम में विभाजित करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.