Concatenate SH command results in one line

3

I'm starting to learn Shell Script and got with a doubt. I am creating a .sh to get the number of processes running in the OS and exporting this information to a .csv file. The problem is that I would like to save the results all in one line.

Exemplo atual:

    DATA
    PROC1
    PROC2

Expected:

DATA PROC1 PROC2

Script:

#!/bin/bash
date +"%Y-%m-%d %H:%M" >> /home/dsadm/LogProcessos/psResults.csv
ps -ef | grep osh | wc -l >> /home/dsadm/LogProcessos/psResults.csv
ps -ef | wc -l >> /home/dsadm/LogProcessos/psResults.csv
    
asked by anonymous 23.08.2018 / 20:58

2 answers

5

There are many ways, this is one:

echo 'date +"%Y-%m-%d %H:%M"' \; 'ps -ef | grep osh | wc -l' \; 'ps -ef | wc -l' >> log.csv

Everything that comes between backticks is executed by the shell, as if the result had been typed in place of the command.

To separate the columns, I used \ escape before ; to not be interpreted as a command line splitter

    
23.08.2018 / 21:06
2

An alternative is to use awk with the command printf , since it prints the contents of each line, but without adding the line break:

awk '{printf $0 " ";}' psResults.csv

With this all the lines of the file are united to be all in one line, separated by space. To do everything in the script, I suggest to create the data in a temporary file and only in the end play the output of awk on the file you need:

#!/bin/bash

# Faz o que precisa no arquivo temporário
date +"%Y-%m-%d %H:%M" >> /tmp/results
ps -ef | grep osh | wc -l >> /tmp/results
ps -ef | wc -l >> /tmp/results

# awk joga tudo no arquivo final
awk '{printf $0 " ";}' /tmp/results >> /home/dsadm/LogProcessos/psResults.csv

# apaga o arquivo temporário
rm /tmp/results

I did this because if you do awk ... arquivo > arquivo it can overwrite the file and lose everything (and if it does with >> , it adds content at the end of the file). Using different files is more secure.

As this is a CSV file, you can change the command to place a comma (or semicolon) instead of space:

# vírgula
awk '{printf $0 ",";}' /tmp/results

# ponto-e-vírgula
awk '{printf $0 ";";}' /tmp/results

The problem is that a comma is left at the end (% with%). You can eliminate this by making a slightly more complex command to check if it is on the last line. Just use DATA,PROC1,PROC2, to count the lines of the file and put it in a variable, which will be used by wc -l :

# coloca vírgula entre os registros, exceto depois do último
awk -v last="$(wc -l < /tmp/results)" '{printf $0; if (NR != last) printf ","};' /tmp/results

With this, it only puts the comma if it is not the last record, resulting in awk

Another alternative is to use DATA,PROC1,PROC2 :

sed -e :a  -e 'N;s/\n/ /;ta' psResults.csv 

The sed option joins the current line to the next line, and then N replaces the line break with space. s/\n/ / makes it loop to the label ta , which was defined at the beginning ( a ). That is, it repeats this process of substitution to the end of the file. In the end, all lines are merged into one, separated by space.

You can change to a comma, but it has the same problem as :a (puts a comma at the end).

    
23.08.2018 / 21:08