Two questions about my script : apply to all my csv and recover filename ?

Hello,

I allow me to writing here to seek your assistance about my script bash !

I have many csv files that looks like :

MO2PPC20,60,1.5,4
MO2PPC20,39,0.3,5
MO2PPC20,105,2.0,4
MO2PPC20,91,2.0,4
MO2PPC20,79,0.4,4
MO2PPC20,62,1.2,3
MO2PPC20,69,0.3,4
MO2PPC20,60,0.6,4
MO2PPC20,60,1.2,4
MO2PPC20,12,0.5,1
MO2PPC20,130,1.5,11
MO2PPC20,180,0.5,3

The first column is the name of my frame, the second the RAM, the third is the CPU1 value and the last column is the CPU2 value

I want to display thoses informations like that :

 
FRAME : MO2PPC20 ========================================

RAM : 60
CPU 1 : 1.5
CPU 2 : 4

RAM : 39
CPU 1 : 0.3
CPU 2 :5

etc...

So, to do that, I use this little script :

#!/bin/bash

OLDIFS=$IFS
IFS=","


while read FRAME RAM CPU1 CPU2
do
    if [[ $FRAME != $PREV ]]
    then
        PREV="$FRAME"
        echo -e "FRAME : $FRAME \
========================================\n"
fi

echo -e "RAM :\t$RAM\n\
CPU 1 :\t$CPU1\n\
CPU 2 :\t$CPU2\n"
echo ""
done < <(sort "my_csv_file.csv")

 

My script works well in the case that I have one file in process.

So my first question is :

How to apply this script to all my csv in my directory ?

I think something like this :

 
for i in ` ls *.csv`
do
./my_script $i
done

And change the last line of my script for something simple such as :

 #!/bin/bash

OLDIFS=$IFS
IFS=","


while read FRAME RAM CPU1 CPU2
do
    if [[ $FRAME != $PREV ]]
    then
        PREV="$FRAME"
        echo -e "FRAME : $FRAME \
========================================\n"
fi

echo -e "RAM :\t$RAM\n\
CPU 1 :\t$CPU1\n\
CPU 2 :\t$CPU2\n"
echo ""
done 

But it doesn't work...

And, the second question :

As soon as I am able to apply my script to all my csv, the informations from my csv will be display without distinction... I want to be able to display the file in process by my script like that :

File : my_csv_1.csv

FRAME : MO2PPC20 ========================================

RAM : 60
CPU 1 : 1.5
CPU 2 : 4

RAM : 39
CPU 1 : 0.3
CPU 2 :5


File : my_csv_2.csv

FRAME : XXXXXX

RAM : XXX
CPU 1 : XXX
CPU 2 : XXX


etc ...

Do you have any solutions for theses two questions ?

Thank you ! :slight_smile:

You need to supply the read command with something to read from. Which you did in the first version, but which you missed in the second. Either redirect the last line from the first positional parameter when calling the script as you do now, or redirect the entire script's stdin from $i in the caller.
Same two options for the file name: Either echo $i in the caller, or echo $1 early in the script itself.

Most efficient with awk:

awk -F, 'p1!=$1 { print "\nFRAME :", p1=$1i, "=====" } { print "\nRAM :", $2; for (i=3; i<=NF; i++) print "CPU ", i-2, ":", $i }'  *.csv

The same can be done with shell:

#!/bin/bash
pframe=
# loop over my arguments
for arg
do
  while IFS=, read -a col
  do
    if [[ $col != $pframe ]]
    then
      pframe=$col
      echo "
FRAME : $col ========================================"
    fi
    echo "
RAM : ${col[1]}"
    for ((i=2; i<${#col[@]}; i++))
    do
      echo "CPU $((i-1)) : ${col}"
    done
  done <"$arg" #while
done #for

Hello ! :slight_smile:

Thank you for your answers !

The problem with your proposition is that your script display all FRAMES with all LPARS. At the begin, I used a similary script than yours but to be more efficient, I wanted to display one FRAME with his LPARSs. But thank you for your proposition ! :slight_smile:

I try something like this :

#!/bin/bash

OLDIFS=$IFS
IFS=","

while [[ $# -gt 0 ]]
do
    while read FRAME LPARS RAM CPU1 CPU2
    do
        if [[ $FRAME != $PREV ]]
        then
            PREV="$FRAME"
            echo -e "FRAME : $FRAME \
            ==============================\n"
        fi
           echo -e "LPARS : $LPARS\n\
          RAM : \t$RAM\n\
          CPU1 : \t$CPU1\n\
          CPU2 : \t$CPU2\n"
          echo ""
          done < $1
          shift
done

And that works perfectly.

Still the second question as a problem. I don't know how to put the name of the file in process at the begin of each " Frame list ".

Sorry, an extra i slipped into my awk code. Should be p1=$1 not p1=$1i .

With printing the file names:

awk -F, 'FILENAME!=pFN { printf "File : %s\n\n", pFN=FILENAME }  p1!=$1 { print "FRAME :", p1=$1, "=====\n" } { print "RAM :", $2; for  (i=3; i<=NF; i++) print "CPU " i-2, ":", $i; print "" }'  *.csv

The same with a bash script (run with: ./scriptname.sh *.csv or find ... -exec ./scriptname.sh {} + ):

#!/bin/bash
pframe=
# loop over my arguments
for arg
do
  echo "File : $arg
"
  while IFS=, read -a col
  do
    if [[ $col != $pframe ]]
    then
      pframe=$col
      echo "\
FRAME : $col ========================================
"
    fi
    echo "RAM : ${col[1]}"
    for ((i=2; i<${#col[@]}; i++))
    do
      echo "CPU $((i-1)) : ${col}"
    done
    echo
  done <"$arg" #while
done #for

Simply echo the parameter 1 at the top of your loop (change in red below).

#!/bin/bash

OLDIFS=$IFS
IFS=","

while [[ $# -gt 0 ]]
do
    echo "File : $1"
    while read FRAME LPARS RAM CPU1 CPU2
    do
        if [[ $FRAME != $PREV ]]
        then
            PREV="$FRAME"
            echo -e "FRAME : $FRAME \
            ==============================\n"
        fi
        echo "LPARS : \t$LPARS"
        echo "RAM : \t$RAM"
        echo "CPU1 : \t$CPU1"
        echo "CPU2 : \t$CPU2"
    done < $1
    shift
done

Hello !

Finally I use this script :

awk -F',|;' -v test="$test" '
     NR==1 { 
        split(FILENAME ,a,"[-.]");
      }
      $0 ~ test {
          if(!header++){
              print "DATE ========================== : " a[4] 
          }
          print ""
          print "LPARS :" $2
          print "RAM : " $5
          print "CPU 1 : " $6
          print "CPU 2 : " $7
          print "" 
          print ""
      }' $fn;

That allow me to :

  • Display the name of my csv file and only keep what I want
  • Delete the useless/empty lines

Thank you ! :slight_smile:

1 Like