2014-09-21 28 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。

相关问题