我有一个脚本:
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,1032108
但是我希望第二个for循环将日期放在第一列中,如下所示:
09-20-14,470400,1032124,661826,1032124,43443,1032108
含义
$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,1032108
如果这是一个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,1032108
09-20-15,470400,1032124,661826,1032124,43443,1032108
只需添加第二天的值。
答案 0 :(得分:1)
首先,有一些简单的方法可以生成以逗号分隔的列表。我经常使用的是paste -sd,
,它要求值在不同的行上。这很容易安排:
printf %s\\n "${WORKSPACES[@]}" | paste -sd,
但如果我们要通过实用程序管道printf
,我们也可以将逗号放入printf
并删除我们不想要的那个:
printf ,%s "{WORKSPACES[@]}" | cut -c2-
cut
和paste
都会保证输出结尾处有换行符。在这种情况下,它似乎是所期望的,但如果不是,您可以使用"$(...)"
来消除换行符:
printf %s "$(printf ,%s "{WORKSPACES[@]}" | cut -c2-)"
额外增加的奖励:使用bash one-liner生成_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/}"
是一个迭代搜索和替换;也就是说,搜索和替换依次应用于数组的每个元素,创建一个单独的&#34;字&#34;对于每个元素。在这种情况下的模式是#
,这里的意思是&#34;从行的开头开始的空模式&#34;。替换在第二个/
之后立即开始,我们不会(并且不得)反斜杠 - 转义以下/
,因为bash不会期望替换为/
(如果我们将反斜杠放入,则反斜杠将被复制到替换中)。我鼓励您尝试echo
以及各种搜索和替换字符串,以便掌握它。
答案 1 :(得分: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,1032108
第二遍:
sideshow
,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used
09-20-14,470400,1032124,661826,1032124,43443,1032108
09-20-14,470400,1032124,661826,1032124,43443,1032108
第三遍:
sideshow
,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used
09-20-14,470400,1032124,661826,1032124,43443,1032108
09-20-14,470400,1032124,661826,1032124,43443,1032108
09-20-14,470400,1032124,661826,1032124,43443,1032108
因此,当我每天用cron运行时,日期会发生变化。非常棒的工作,谢谢@rici。