sed with special characters

Hi,

I am reading a file (GC_JAR.log) which has entries like:

511725.629, 0.1122672 secs]
525268.975, 0.1240036 secs]
527181.835, 0.2068215 secs]
527914.287, 0.2884801 secs]
528457.134, 0.2548725 secs]

I want to replace all the entries of "secs]" with just "secs"

Thus, the output should be like:

511725.629, 0.1122672 secs
525268.975, 0.1240036 secs
527181.835, 0.2068215 secs
527914.287, 0.2884801 secs
528457.134, 0.2548725 secs

I tried using sed but it's not working for some reason. I read line by line from the original file ( GC_JAR.log ) and dump the final output in GC_cycles.csv

# !/bin/bash
SOURCE=secs\]
TARGET=secs
cat GC_JAR.log | while read line
do
echo "${line}" | sed 's/"${SOURCE}"/"${TARGET}"/g' >> GC_cycles.csv
done

Any ideas please? what's going wrong with sed command there.

single quotes stop variable expansion

# !/bin/bash
SOURCE=secs\]
TARGET=secs
sed "s/${SOURCE}/${TARGET}/g" GC_JAR.log  > GC_cycles.csv

Thanks! that works

I am newbie.. still learning how to use single quotes and double quotes :slight_smile:

I still need to do another operation on the file

With the above sed operation, I get the output file as below ( GC_cycles.csv)

511725.629, 0.1122672 secs
525268.975, 0.1240036 secs
527181.835, 0.2068215 secs
527914.287, 0.2884801 secs
528457.134, 0.2548725 secs

Now, I want to convert the first field ( which is in seconds currently) to hours.

I used the following:

echo "Converting seconds to hours"
cat GC_cycles.csv | while read line
do
X=`echo "${line}" | awk -F"," '{ print $1}'` # X is the first field
X=`echo $X / 60/ 60 | bc` # Convert seconds to hours
Y=`echo "${line}" | awk -F"," '{ print $2}'` # Y is the second field
echo $X "hrs" "," $Y >> Final_GC_cycles.csv
done

Now I get the output as:

142 hrs , 0.1122672 secs
145 hrs , 0.1240036 secs
146 hrs , 0.2068215 secs
146 hrs , 0.2884801 secs
146 hrs , 0.2548725 secs

There are 2 things which I want to look at:
1) the value of X is coming in integer. How can I get it to be a floating number? with rounding to 1 decimal place.
2) Is there a more efficient way to write the above code?

What you have looks fine, just replace the bc line with this:

X=`echo "scale=1;$X / 60/ 60" | bc` # Convert seconds to hours, with 1 decimal.

The "scale" variable defines your precision. It's documented in the "bc" man page. :slight_smile:

I've added my version of your program above:

#! /bin/bash

cat data | sed 's/,//g' |
while read a b c
do
x=$(echo "scale=1;$a/60/60" | bc)
echo "$x hrs, $b $c"
done

And this was done without the need of calling awk; of course I called "sed" and "bc". but I think you get the idea.

When using perl I use the time module for conversions. In shell it is a bit more work. Here is a function I use for converting seconds, which you can include in your script

 convert_seconds() {
   time="$1"
   days=$(expr $time / 86400)
   hour1=$(expr $time / 3600)
   hour2=$(expr $days \* 24)
   hours=$(expr $hour1 - $hour2)
   minute1=$(expr $time / 60)
   minute2=$(expr $days \* 1440)
   minute3=$(expr $hours \* 60)
   minutes=$(expr $minute1 - $minute2 - $minute3)
   second1=$(expr $minutes \* 60)
   second2=$(expr $hours \* 3600)
   second3=$(expr $days \* 1440)
   seconds=$(expr $time - $second1 - $second2 - $second3)

   echo "
     days   =$days
     hours  =$hours
     minutes=$minutes
     seconds=$seconds
   "
}
if [[ -n $1 ]]; then
  convert_seconds $1
fi