2014-09-21 65 views
0

我有一個腳本:For循環,產生附加價值的一個逗號分隔的字符串

OUTPUT_DIR=/share/es-ops/Build_Farm_Reports/WorkSpace_Reports 
    BASE=/export/ws 
    TODAY=`date +"%m-%d-%y"` 
    HOSTNAME=`hostname` 
    WORKSPACES=("bob_avail" "bob_used" "mel_avail" "mel_used" "sideshow-ws2_avail" "sideshow-ws2_used") 
    if ! [ -f $OUTPUT_DIR/$HOSTNAME.csv ] && [ $HOSTNAME == "sideshow" ]; then 
    echo "$HOSTNAME" > $OUTPUT_DIR/$HOSTNAME.csv # with a linebreak 
    separator="," # defined empty for the first value 
    for v in "${WORKSPACES[@]}" 
    do 
     echo -n "$separator$v" >> $OUTPUT_DIR/$HOSTNAME.csv # append, concatenated, the separator and the value to the file 
     #separator="," # comma for the next values 
    done 
    echo >> $OUTPUT_DIR/$HOSTNAME.csv # add a linebreak (if you want it) 
    fi 
    WORKSPACES2=("bob" "mel" "sideshow-ws2") 
    separator="" # defined empty for the first value 
    for v in "${WORKSPACES2[@]}" 
    do 
     echo -n "$separator`df -m $BASE/$v | awk '{if (NR!=1) {print $3","$2}}'`" >> $OUTPUT_DIR/$HOSTNAME.csv 
     separator="," # comma for the next values 
    done 

產生這樣的:

sideshow 
,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used 
470400,1032124,661826,1032124,43443,8 

但我想第二個for循環放於日期第一列是這樣的:

09-20-14,470400,1032124,661826,1032124,43443,8 

意義

$TODAY,<bob avail>,<bob used>,mel avail>,<mel used>,<sideshow-ws2 avail>,<sideshow-ws2 used> 

所以整體的輸出應該是這樣的:

sideshow 
,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used 
09-20-14,470400,1032124,661826,1032124,43443,8 

,如果這則運行了一個cron我只需要檢查主機名是x和.csv文件確實存在,則:

sideshow 
,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used 
09-20-14,470400,1032124,661826,1032124,43443,8 
09-20-15,470400,1032124,661826,1032124,43443,8 

只需添加第二天的值。

+0

你希望與'-n'相同的技巧。循環「WORKSPACES2」,運行這兩個命令,將它們都回顯到文件中,然後繼續。 (實際上你只需要運行一次命令,使用'{print $ 3','$ 2}'。) – 2014-09-21 01:04:59

+0

由於某種原因,第一列沒有得到第一列的日期。我把輸出粘貼到我的問題中。 – 2014-09-21 02:02:37

+0

您不能像工作區一樣遍歷日期。在循環之前,你只需'將'-n'回顯給文件。 – 2014-09-21 02:07:55

回答

1

首先,有幾個簡單的方法來產生逗號分隔列表。我通常使用的是paste -sd,,它要求值分開。這可以很容易地被安排:

printf %s\\n "${WORKSPACES[@]}" | paste -sd, 

但如果我們通過一個工具去管printf,我們不妨把逗號與printf和刪除,我們不希望一個:

printf ,%s "{WORKSPACES[@]}" | cut -c2- 

cutpaste都將保證在其輸出結尾處有換行符。在這種情況下,它似乎是有什麼期望,但如果不是這樣,你可以使用"$(...)"消除換行符:

printf %s "$(printf ,%s "{WORKSPACES[@]}" | cut -c2-)" 

額外的好處:有一個bash一行程序產生_avail_used標籤:

paste -d, <(printf %s_avail\\n "${WORKSPACES2[@]}") \ 
      <(printf %s_used\\n "${WORKSPACES2[@]}") | paste -sd, 

現在,讓我們考慮DF調用。您需要六次調用df才能使用功能非常強大的工具(awk)提取各個字段,這些工具可以爲您完成所有工作。讓我們這樣做。首先,我們將告訴df關於我們想要的所有文件系統,然後我們可以處理所有的行,並提取兩個字段並用逗號輸出。作爲一個額外的好處,我們可以輸出時間戳,太:

WORKSPACES2=("bob" "mel" "sideshow-ws2") 
df -m "${WORKSPACES2[@]/#//export/ws/}" | awk ' 
    BEGIN { print strftime("%m-%d-%y")} 
    NR > 1 { printf ",%s,%s", $3, $2; } 
    END { printf "\n"}' >> "$OUTPUT_DIR/$HOSTNAME.csv" 

上述假設了GNU AWK,其中有一個strftime功能。與其他awks,你要調用一個shell:

df -m "${WORKSPACES2[@]/#//export/ws/}" | awk ' 
    BEGIN { "date +%m-%d-%y" | getline date; 
      printf "%s",date } 
    NR > 1 { printf ",%s,%s", $3, $2; } 
    END { printf "\n"}' >> "$OUTPUT_DIR/$HOSTNAME.csv" 

bash表達"${WORKSPACES2[@]/#//export/ws/}"是一個迭代搜索和替換;也就是說,搜索和替換依次應用於數組的每個元素,爲每個元素創建一個單獨的「單詞」。在這種情況下的模式是#,其在這裏意味着「從行的開始處開始的空模式」。在第二個/之後立即開始替換,並且我們不會(也不一定)反斜槓 - 逃避以下/,因爲bash不會在替換中預期跟隨/(如果我們放置它們,反斜槓將被複制到替換中在)。我鼓勵你試驗echo和各種搜索和替換字符串,以獲得它的掛鉤。

+0

有沒有辦法像上面顯示的那樣將日期放在第一列中? – 2014-09-21 02:18:06

+0

@BrianBills:是的,我剛剛補充說。 – rici 2014-09-21 02:19:02

+0

如何將輸出回顯到.csv文件?當第二天cron啓動時,我希望你的輸出打印在前面的底線之下。 – 2014-09-21 02:21:38

0

隨着@rici我能得到的一切工作,我想要的方式幫助:

OUTPUT_DIR=/share/es-ops/Build_Farm_Reports/WorkSpace_Reports 
    BASE=/export/ws 
    TODAY=`date +"%m-%d-%y"` 
    HOSTNAME=`hostname` 
    WORKSPACES=("bob_avail" "bob_used" "mel_avail" "mel_used" "sideshow-ws2_avail" "sideshow-ws2_used") 
    if ! [ -f $OUTPUT_DIR/$HOSTNAME.csv ] && [ $HOSTNAME == "sideshow" ]; then 
    echo "$HOSTNAME" > $OUTPUT_DIR/$HOSTNAME.csv # with a linebreak 
    separator="," # defined empty for the first value 
    for v in "${WORKSPACES[@]}" 
    do 
     echo -n "$separator$v" >> $OUTPUT_DIR/$HOSTNAME.csv # append, concatenated, the separator and the value to the file 
     #separator="," # comma for the next values 
    done 
    echo >> $OUTPUT_DIR/$HOSTNAME.csv # add a linebreak (if you want it) 
    WORKSPACES2=("bob" "mel" "sideshow-ws2") 
    df -m "${WORKSPACES2[@]/#//export/ws/}" | awk ' 
     BEGIN { "date +'%m-%d-%y'" | getline date; 
       printf "%s",date } 
     NR > 1 { printf ",%s,%s", $3, $2; } 
     END { printf "\n"}' >> "$OUTPUT_DIR/$HOSTNAME.csv" 
    elif [ $OUTPUT_DIR/$HOSTNAME.csv ] && [ $HOSTNAME == "sideshow" ]; then 
    WORKSPACES2=("bob" "mel" "sideshow-ws2") 
    df -m "${WORKSPACES2[@]/#//export/ws/}" | awk ' 
     BEGIN { "date +'%m-%d-%y'" | getline date; 
       printf "%s",date } 
     NR > 1 { printf ",%s,%s", $3, $2; } 
     END { printf "\n"}' >> "$OUTPUT_DIR/$HOSTNAME.csv" 
    else 
    : 
    fi 

在第一遍產生輸出:

sideshow 
    ,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used 
    09-20-14,470400,1032124,661826,1032124,43443,8 

第二關:

sideshow 
    ,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used 
    09-20-14,470400,1032124,661826,1032124,43443,8 
    09-20-14,470400,1032124,661826,1032124,43443,8 

第三關:

sideshow 
    ,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used 
    09-20-14,470400,1032124,661826,1032124,43443,8 
    09-20-14,470400,1032124,661826,1032124,43443,8 
    09-20-14,470400,1032124,661826,1032124,43443,8 

因此,當我每天用cron運行這個日期時,日期將會改變。非常棒的工作,謝謝@rici。