【问题标题】:Append elements of an array to the end of a line将数组的元素附加到行尾
【发布时间】:2014-11-15 04:26:10
【问题描述】:

首先让我说我在 stackoverflow.com 上关注了与我的问题相关的问题,但似乎规则不适用。让我给你看看。

以下脚本:

    #!/bin/bash
    OUTPUT_DIR=/share/es-ops/Build_Farm_Reports/WorkSpace_Reports
    TODAY=`date +"%m-%d-%y"`
    HOSTNAME=`hostname`
    WORKSPACES=( "bob" "mel" "sideshow-ws2" )
    if ! [ -f $OUTPUT_DIR/$HOSTNAME.csv ] && [ $HOSTNAME == "sideshow" ]; then
    echo "$TODAY","$HOSTNAME" >  $OUTPUT_DIR/$HOSTNAME.csv
    echo "${WORKSPACES[0]}," >> $OUTPUT_DIR/$HOSTNAME.csv
    sed -i "/^'"${WORKSPACES[0]}"'/$/'"${WORKSPACES[1]}"'/" $OUTPUT_DIR/$HOSTNAME.csv
    sed -i "/^'"${WORKSPACES[1]}"'/$/${WORKSPACES[2]}"'/" $OUTPUT_DIR/$HOSTNAME.csv
    fi

我希望输出看起来像:

09-20-14,sideshow
bob,mel,sideshow-ws2

sed 语句应该将连续的数组元素附加到同一行上的前面的元素。现在我知道有一种更简单的方法可以做到这一点:

echo "${WORKSPACES[0]},${WORKSPACES[1]},${WORKSPACES[2]}" >> $OUTPUT_DIR/$HOSTNAME.csv

但是假设我在数组中有 30 个元素,我想将它们一个接一个地附加到同一行?你能告诉我如何循环遍历数组中的元素并将它们一个接一个地附加到同一行吗?

另外假设我有如下命令的输出:

df -m /export/ws/$ws | awk '{if (NR!=1) {print $3}}'

我想将它附加到同一行的末尾。

但是当我运行它时,我得到:

    + OUTPUT_DIR=/share/es-ops/Build_Farm_Reports/WorkSpace_Reports
    ++ date +%m-%d-%y
    + TODAY=09-20-14
    ++ hostname
    + HOSTNAME=sideshow
    + WORKSPACES=("bob" "mel" "sideshow-ws2")
    + '[' -f /share/es-ops/Build_Farm_Reports/WorkSpace_Reports/sideshow.csv ']'

文件现在看起来像:

09-20-14,sideshow
bob,

我很高兴地报告用户 syme 解决了这个问题 (see below) 但后来我意识到我需要第一列中的日期:

09-7-14,bob,mel,sideshow-ws2

我可以使用syme's for 循环来做到这一点吗?

好的用户syme也解决了这个问题,他说"Just add $TODAY to the for loop"是这样的:

for v in "$TODAY" "${WORKSPACES[@]}"

好的,现在输出看起来像这样I changed the elements in the array btw

sideshow
09-20-14,bob_avail,bob_used,mel_avail,mel_used,sideshow-ws2_avail,sideshow-ws2_used

现在,下一行将由第一列中的, 填充,跳过日期,然后:

df -m /export/ws/$v | awk '{if (NR!=1) {print $3}}

等于第一次迭代中 bob 上可用空间的值

然后:

df -m /export/ws/$v | awk '{if (NR!=1) {print $2}}

等于第二次迭代中 bob 上已用空间的值

然后我们就转到${WORKSPACE[@]}中的下一个值

这将是 mel 并像我们在上面对 bob 或 $v 所做的那样提供和使用。

我知道你们这里的天才会把这当儿戏。

我在这个帖子上解决了我自己的最后一个问题:

    WORKSPACES2=( "bob" "mel" "sideshow-ws2" )
    separator="," # defined empty for the first value
    for v in "${WORKSPACES2[@]}"
    do
    available=`df -m /export/ws/$v | awk '{if (NR!=1) {print $3}}'`
    used=`df -m /export/ws/$v | awk '{if (NR!=1) {print $2}}'`
      echo -n "$separator$available$separator$used" >> $OUTPUT_DIR/$HOSTNAME.csv # append, concatenated, the separator and the value to the file
    done

产生:

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

【问题讨论】:

  • sed 的 2 行上的反引号未关闭。但我不认为这是你的问题。我只是不明白你想用这 2 行做什么: 1. sed -i 修改给定的文件,预计没有输出(由echo 打印)。 2.语法错误字符9开头sed(如您所见...),您要sed做什么? 3.您不应该使用反引号(不推荐),而是使用 $(...) 。 4. 我认为你应该检查一下你的"s 和's,它们太奇怪了。
  • 我去掉了echo>> 并加上了后面的记号,但我仍然遇到同样的错误。我想要 sed 做的是在第二行输出bob,mel,sideshow-ws2。感谢您的帮助。
  • 再次:我不明白你想用 sed 做什么?如果只想打印用, 分隔的WORKSPACES 的值,只需使用重定向echo "${WORKSPACES[0]},${WORKSPACES[1]},${WORKSPACES[2]}" 吗?不 ?我不明白。
  • 当然,我听说你在这个例子中适用,但是对于更大的列表和从命令输出派生的值,应该有一种方法将变量传递给 sed,这样你就可以追加.这个脚本只是一个更大的脚本的开始。但我喜欢你的想法。好吧,假设我在数组中有 15 个元素。你能告诉我一个 for 循环,它会在每次循环迭代时改变 `[@]' 中的数字吗?
  • 哦,好的!我要发布一个答案。

标签: arrays bash loops sed


【解决方案1】:

echo -n 允许打印没有换行符的文本。

要遍历数组的值,可以使用 for 循环:

echo "$TODAY,$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)

【讨论】:

  • 如果我想将$TODAY 放在第一列中,例如:09-7-14,bob,mel,sideshow-ws2
  • 只需将其添加到for循环列表中:for v in "$TODAY" "${WORKSPACES[@]}"
  • 谢谢你。如果我还有其他问题,我应该将其添加到同一个问题中还是开始另一个主题?
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 2021-07-04
  • 2017-03-03
  • 2018-08-18
  • 2014-02-24
  • 1970-01-01
相关资源
最近更新 更多