簡體   English   中英

BASH輸出列格式

[英]BASH output column formatting

第一次發帖。 你好,世界。 處理我的第一個腳本,只是檢查我的網站列表是否在線,然后返回HTTP代碼以及將其返回到桌面上另一個文件所花費的時間。

- 這篇文章將在MAC OSX上運行 -

我想修改我的腳本,以便將其輸出格式化為3個整齊的列。

目前

#!/bin/bash
file="/Users/USER12/Desktop/url-list.txt"
printf "" > /Users/USER12/Desktop/url-results.txt
while read line
do
    printf "$line" >> /Users/USER12/Desktop/url-results.txt
    printf "\t\t\t\t" >> /Users/USER12/Desktop/url-results.txt
    curl -o /dev/null --silent --head --write-out '%{http_code} %{time_total}' "$line" >> /Users/USER12/Desktop/url-results.txt
    printf "\n" >> /Users/USER12/Desktop/url-results.txt
done <"$file"

以下列格式輸出

google.com              200 0.389
facebook.com                200 0.511
abnormallyLongDomain.com                200 0.786

但我想格式化為整齊的對齊列,以便於閱讀

DOMAIN_NAME                 HTTP_CODE   RESPONSE_TIME
google.com                  200         0.389
facebook.com                200         0.511
abnormallyLongDomain.com    200         0.486

謝謝大家的幫助!!

column非常好。 但是,您已經在使用printf ,它可以很好地控制輸出格式。 使用printf的功能還可以使代碼有所簡化:

#!/bin/bash
file="/Users/USER12/Desktop/url-list.txt"
log="/Users/USER12/Desktop/url-results.txt"
fmt="%-25s%-12s%-12s\n"
printf "$fmt" DOMAIN_NAME HTTP_CODE RESPONSE_TIME > "$log"
while read line
do
    read code time < <(curl -o /dev/null --silent --head --write-out '%{http_code} %{time_total}' "$line")
    printf "$fmt" "$line" "$code" "$time" >> "$log"
done <"$file"

使用上面定義的格式,輸出看起來像:

DOMAIN_NAME              HTTP_CODE   RESPONSE_TIME
google.com               301         0.305
facebook.com             301         0.415
abnormallyLongDomain.com 000         0.000

您可以通過更改腳本中的fmt變量來微調輸出格式,例如間距或對齊。

進一步改進

上面的代碼用每個循環打開和關閉日志文件。 這可以像Charles Duffy建議的那樣避免,只需使用exec在第一個printf語句之前將stdout重定向到日志文件:

#!/bin/bash
file="/Users/USER12/Desktop/url-list.txt"
exec >"/Users/USER12/Desktop/url-results.txt"
fmt="%-25s%-12s%-12s\n"
printf "$fmt" DOMAIN_NAME HTTP_CODE RESPONSE_TIME
while read line
do
    read code time < <(curl -o /dev/null --silent --head --write-out '%{http_code} %{time_total}' "$line")
    printf "$fmt" "$line" "$code" "$time"
done <"$file"

或者,正如Chepner建議的那樣,可以將打印語句分組:

#!/bin/bash
file="/Users/USER12/Desktop/url-list.txt"
fmt="%-25s%-12s%-12s\n"
{
printf "$fmt" DOMAIN_NAME HTTP_CODE RESPONSE_TIME
while read line
do
    read code time < <(curl -o /dev/null --silent --head --write-out '%{http_code} %{time_total}' "$line")
    printf "$fmt" "$line" "$code" "$time"
done <"$file"
} >"/Users/USER12/Desktop/url-results.txt"

分組的一個優點是,在組之后,stdout會自動恢復到正常值。

縮短了一點

#!/bin/bash

file="./url.txt"
fmt="%s\t%s\t%s\n"
( printf "$fmt" "DOMAIN_NAME" "HTTP_CODE" "RESPONSE_TIME"
while read -r line
do
    printf "$fmt" "$line" $(curl -o /dev/null --silent --head --write-out '%{http_code} %{time_total}' "$line")
done <"$file" ) | column -t > ./out.txt

不需要重定向每個printf但是您可以將腳本的一部分包含在(...)並在子shell中運行它以重定向它的輸出。 打印用一個選項卡分隔的每個字段,並使用column命令很好地格式化它。

無論如何,通常最好不要將文件名(也不是標題)放入腳本中並將其減少到

#!/bin/bash

while read -r line
do
    printf "%s\t%s\t%s\n" "$line" $(curl -o /dev/null --silent --head --write-out '%{http_code} %{time_total}' "$line")
done | column -t

並使用它像:

myscript.sh < url-list.txt >result.txt

這允許您在管道中使用腳本,例如:

something_produces_urls | myscript.sh | grep 200 > somewhere.txt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM