【问题标题】:How to write the output of a bash command to a csv file?如何将 bash 命令的输出写入 csv 文件?
【发布时间】:2021-02-26 08:05:02
【问题描述】:

我目前在 bash 中使用以下循环跟踪我的机器的内存使用情况:

echo "      date     time $(free -m | grep total | sed -E 's/^    (.*)/\1/g')" | tee -a log20201113.txt
while true; do
    echo "$(date '+%Y-%m-%d %H:%M:%S') $(free -m | grep Mem: | sed 's/Mem://g')" | tee -a log20201113.txt
    sleep 1
done

这给了我一个 txt 文件,里面有类似的东西(修改后的值):

      date     time          total       used       free     shared    buffers     cached
2020-11-13 22:55:56           8333        627       5705          0       1638        685
2020-11-13 22:55:57           8333        677       5656          0       1638        685
2020-11-13 22:55:58           8333        725       5607          0       1638        685
2020-11-13 22:55:59           8333        773       5560          0       1638        685

我正在尝试将其输出到 csv 文件。放置 csv 扩展名似乎不起作用,因为它不包含分隔符。我将如何包含分隔符并将其放入 csv 文件中?

【问题讨论】:

    标签: bash memory memory-management


    【解决方案1】:

    tee 之前通过管道连接到awk '{$1=$1}1' OFS="," 应该足以转换为csv。例如:

    echo "      date     time $(free -m | grep total | sed -E 's/^    (.*)/\1/g')" | awk '{$1=$1}1' OFS="," | tee -a log20201113.csv
    while true; do
        echo "$(date '+%Y-%m-%d %H:%M:%S') $(free -m | grep Mem: | sed 's/Mem://g')" | awk '{$1=$1}1' OFS="," | tee -a log20201113.csv
        sleep 1
    done
    

    产生:

    $ head -n 5 log20201113.csv
    date,time,total,used,free,shared,buff/cache,available
    2020-11-14,17:30:04,3638,1663,765,177,1208,1561
    2020-11-14,17:30:05,3638,1663,765,177,1208,1561
    2020-11-14,17:30:06,3638,1662,766,177,1208,1562
    2020-11-14,17:30:07,3638,1662,767,177,1208,1562
    

    awk 分配给一个字段 ($1=$1) 时,它会

    通过连接由 OFS 分隔的 $i 来重构 $0

    $0 是输入行,$i 是字段,OFS 在我们的例子中是 ,。终止 1 只是一个“始终匹配”的模式,总是使用默认操作 (print) 执行。

    但这也会以csv 格式打印到stdout。如果这是一个问题,并且您希望在终端上保留格式良好的输出并在文件中保留csv,您可以使用此"trick"

    echo "      date     time $(free -m | grep total | sed -E 's/^    (.*)/\1/g')" | tee /dev/tty | awk '{$1=$1}1' OFS="," >> log20201113.csv
    while true; do
        echo "$(date '+%Y-%m-%d %H:%M:%S') $(free -m | grep Mem: | sed 's/Mem://g')" | tee /dev/tty | awk '{$1=$1}1' OFS="," >> log20201113.csv
        sleep 1
    done
    

    【讨论】:

      【解决方案2】:

      在 sed 中尝试管道:

      echo "      date     time $(free -m | grep total | sed -E 's/^    (.*)/\1/g')" | tee -a log20201113.txt
      while true; do
          echo "$(date '+%Y-%m-%d %H:%M:%S') $(free -m | grep Mem: | sed 's/Mem://g')" | tee -a log20201113.txt
          sleep 1
      done | sed "s/\s\+/,/g"
      

      sed 将用逗号替换空格,然后你就可以使用 csv。

      你可以直接从文本文件中做:

      sed -i "s/\s\+/,/g" yourfile.txt,它会用逗号替换所有空格。

      然后你得到

      2020-11-14,17:42:42,7748,2190,729,601,4828,4490
      2020-11-14,17:42:43,7748,2189,733,598,4825,4494
      

      【讨论】:

        【解决方案3】:

        这是 GNU awk 中的一个,它从 /proc/meminfo 读取内存信息:

        $ gawk '
        @load "time"                                  # sleep
        BEGIN {
            OFS=","                                   # field separator
            printf "%s%s%s%s%s%s%s",                  # header
                "date time" OFS,
                "total" OFS,
                "used" OFS,
                "free" OFS,
                "shared" OFS,
                "buffers" OFS,
                "cached" ORS
            while(1) {                                # keep looping
                while((getline < "/proc/meminfo")>0)
                    a[$1]=$2
                printf "%s%s%s%s%s%s%s",
                    strftime("%F%T") OFS,
                    a["MemTotal:"] OFS,
                    a["MemTotal:"]-a["MemFree:"]-a["Buffers:"]-a["Cached:"]-a["SReclaimable"] OFS,
                    a["MemFree:"] OFS,
                    a["ShmemHugePages:"] OFS,
                    a["Buffers:"] OFS,
                    a["Buffers:"]+a["SReclaimable:"] ORS
                sleep(1)
            }
        }'
        

        输出:

        date time,total,used,free,shared,buffers,cached
        2020-11-1419:12:42,16135228,6586304,6713024,0,213652,362516
        2020-11-1419:12:43,16135228,6586304,6713024,0,213652,362516
        ...
        

        【讨论】:

          猜你喜欢
          • 2023-03-11
          • 1970-01-01
          • 2021-12-23
          • 2012-02-18
          • 2020-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多