2

This question already has an answer here:

So say I've got a file with the following text in it.

And the source file I'm reading is like this:

#0  abc 2016-08-06 01:12:57 AM  9.1%    779.9M of 1G    156.3M of 1G
#1  abc 2016-08-06 02:33:47 AM  12.1%   339.9M of 1G    126.3M of 1G

The following is the script I'm using

#!/bin/bash

opFile="opfile.txt"
sourceFile="TestOutput"

    if [[ ! -e "$opFile" ]]
    then
    {
        touch $opFile
        count=0
        grep "#" "$sourceFile" | while read -r line ; do
        {
            cpu=$(grep "#$count" "$sourceFile" | cut -f 4 | cut -d% -f1)
            mem=$(grep "#$count" "$sourceFile" | cut -f 5 | cut -dM -f1)
            disk=$(grep "#$count" "$sourceFile" | cut -f 6 | cut -dM -f1)
            echo -e "$cpu\n$mem\n$disk" >> "$opFile"
            ((count++))
        }   
        done

    }
    else
    {
        count=0
        lineCounter=0
        grep "#" "$sourceFile" | while read -r line ; do
        {
            cpu=$(grep "#$count" "$sourceFile" | cut -f 4 | cut -d% -f1)
            mem=$(grep "#$count" "$sourceFile" | cut -f 5 | cut -dM -f1)
            disk=$(grep "#$count" "$sourceFile" | cut -f 6 | cut -dM -f1)
            ((lineCounter++))
            sed ""$lineCounter"s/$/,"$cpu"/" "$opFile" | tee "$opFile"
            ((lineCounter++))
            sed ""$lineCounter"s/$/,"$mem"/" "$opFile" | tee "$opFile" 
            ((lineCounter++))
            sed ""$lineCounter"s/$/,"$disk"/" "$opFile" | tee "$opFile" 
            ((count++))

        }
        done
    }
    fi

Now, the script needs to be run multiple times on that $sourceFile since the numbers in that file would keep changing. So the first time the script runs, the output is so

9.1
779.9
156.3
12.1
339.9
126.3

And the second time it runs (assuming the values are the same in the source file), the output should look like.

9.1,9.1
779.9,779.9
156.3,156.3
12.1,12.1
339.9,339.9
126.3,126.3

Now, the sed line I've used is correct, I'm pretty sure, but I'm having issues when it comes to putting that in the file. I could've used the >> output redirecter but that's printing everything on a new line. Tee is working slightly unexpectedly, sometimes it'd doing the right thing, other times, my opfile.txt is empty. Any idea on how to put my sed output in the file correctly? And no, preferably, I wouldn't want anything displayed on the stdout.

Thanks!

marked as duplicate by ilkkachu, G-Man, mdpc, Thomas Dickey, Networker Aug 30 '16 at 11:49

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    What part of this is fixed vs variable? Your loop always happens twice? The a,b,c variables get values from some other processing? Only lines 1-3 get updated in the first loop, and 4-6 in the second? – Jeff Schaller Aug 28 '16 at 12:24
  • My apologies. Have added in the necessary details. And yes, on the first iteration, if you see the edit, my 3 variables will get values since grep will return that first line. The second time it runs, it will retrieve the next 3 values. Outputting it the first time is easy. But now I need to append the values with commas to the previous lines. – Izy- Aug 28 '16 at 13:59
  • I made another edit with a possible solution. Optimizations are welcome but the sed line I've used works only in the command line and not when run in a shell script. Any ideas why? – Izy- Aug 28 '16 at 14:56
  • Post your whole script, not just a snippet. – Gilles Aug 28 '16 at 23:36
  • Done @Gilles. Please do have a look. – Izy- Aug 29 '16 at 14:24
0

What was wrong was that I was trying to write into the same file that I was reading from. So when you use > to write into a file, when the file is opened, it is truncated before sed can get put it's contents in it and hence the empty file (is what I think, correct me if I'm wrong). Similar must've been the logic for why tee worked so unexpec(tee)dly.

Finally, a work around suggested by a stackoverflow friend did the trick in a much easier way.

paste -d, output.txt <(grep -oP '[0-9.]+(?=%)|[0-9.]+(?=[A-Z]+ of)' source.txt) > tmp ; mv tmp output.txt

So here, to prevent this dirty read sort of issue from happening, a temporary file was used. Thanks for your help everyone.

Not the answer you're looking for? Browse other questions tagged or ask your own question.