0
votes

Comment écrire la sortie d'une commande bash dans un fichier csv?

Je suis actuellement l'utilisation de la mémoire de ma machine en utilisant la boucle suivante dans bash:

      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

Ce qui me donne un fichier txt avec quelque chose comme ça (valeurs modifiées):

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

J'essaye de sortir cela dans un fichier csv à la place. Mettre une extension csv ne semble pas fonctionner car elle n'inclut pas de séparateurs. Comment pourrais-je inclure des séparateurs et les mettre dans un fichier csv à la place?


0 commentaires

3 Réponses :


1
votes

essayez la tuyauterie dans sed:

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

le sed remplacera les espaces par des virgules, alors vous avez csv.

à partir du fichier texte directement, vous pouvez faire:

sed -i "s/\s\+/,/g" yourfile.txt , il remplacera tout espacé par une virgule.

alors vous obtenez

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"


0 commentaires

1
votes

piping to awk '{$1=$1}1' OFS="," avant tee devrait être suffisant pour convertir en csv . par exemple:

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

produit:

$ 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

quand awk assigne à un champ ( $1=$1 ) il le fera

fait reconstruire $ 0 en concaténant les $ i séparés par OFS

$0 est la ligne d'entrée, $i sont les champs et OFS est , dans notre cas. le 1 final est juste un motif "toujours correspondre" qui est toujours exécuté avec l'action par défaut ( print ).

mais cela sera également imprimé sur stdout au format csv . si cela pose un problème et que vous souhaitez conserver une sortie joliment formatée sur le terminal et csv dans le fichier, vous pouvez utiliser cette "astuce" :

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


0 commentaires

0
votes

En voici un dans GNU awk, qui lit les informations de mémoire dans /proc/meminfo :

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
...

Production:

$ 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)
    }
}'


0 commentaires