Issue
I want to plot some data of a spray simulation. There is a variable called the vaporpenetrationlength, which describes the distance from the injector to the position where the mass fraction is 0.1%. The simulation created many folders for each time step. Inside those folders there is one file which contains the mass fraction and the distance. I want to create a script which goes through all the time step folders and search inside this one file and prints out the distance where the 0.1% were measured and in which time step it was. I found a script, but I don't understand it because I just started to learn shell scripting. Could someone please help me step by step in building such a script? I am interested in learning it, and therefore I want to understand ever line of the code. Thanks in advance :)
Here are the files which contains the data to be extracted from: https://drive.google.com/drive/folders/1x5GNg5uOhsx2w3hjutHn49zSY5i7okjz?usp=sharing
#!/bin/bash
if [ -f "VapPen.txt" ]; then
gnuplot -e "set title 'Verdunstungspenetration'; set xlabel 'Zeit [s]' ;set ylabel 'Verdunstungspenetrationslänge [m]'; set grid; plot 'VapPen.txt' using 1:2 with linespoints title 'Vapor penetraion 0,1% mass'; pause -1"
else
echo VapPen [m] > vappen.txt
echo Time [s] > time.txt
for f in postProcessing/singleGraphVapPen/*
do
for g in $f/*
do
echo $f
vappen=0
while read -r length yheptane; do
yhepE=$(echo $yheptane | tr e E)
ymax=0.001
if (( $(awk 'BEGIN {print('$yhepE' >= '$ymax')}') )); then
vappen=$length
fi
done < "$g"
echo $vappen >>vappen.txt
echo $f | cut -d'/' -f3 >>time.txt
done
done
echo "plotting..."
paste time.txt vappen.txt >VapPen2.txt
grep "Time" VapPen2.txt >VapPen.txt
grep "e-07" VapPen2.txt >>VapPen.txt
grep "e-06" VapPen2.txt >>VapPen.txt
grep "e-05" VapPen2.txt >>VapPen.txt
grep "e-04" VapPen2.txt >>VapPen.txt
grep -v "e" VapPen2.txt >>VapPen.txt
rm VapPen2.txt time.txt vappen.txt
gnuplot -e "set title 'Verdunstungspenetration'; set xlabel 'Zeit [s]' ;set ylabel 'Verdunstungspenetrationslänge [m]'; set grid; plot 'VapPen.txt' using 1:2 with linespoints title 'Vapor penetraion 0,1% mass'; pause -1"
fi
Solution
This little script outputs Time
TabLength
TabMass
based on the value of the "mass fraction":
printf '%s\t%s\t%s\n' 'Time' 'Length' 'Mass'
awk '
BEGIN { FS = OFS = "\t"}
FNR == 1 {
n = split(FILENAME,path,"/")
time = sprintf("%0.7f",path[n-1])
}
NF != 2 {next}
0.001 <= $2 && $2 < 0.00101 { print time,$1,$2 }
' postProcessing/singleGraphVapPen/*/*
remark: In fact, printing the header could be done within the awk
program, but doing it with a separate printf
command allows you to post-process the output of awk
(for ex. if you need to sort the times and/or lengths and/or masses).
notes:
FNR == 1
is true for the first line of each input file. In the corresponding block, I extract thetime
value from the directory name.NF != 2 {next}
is for filtering out thegnuplot
commands that are at the beginning of the input files. In words, this statement means "if the number of (tab-delimited) fields in the line isn't2
, then skip"0.001 <= $2 && $2 < 0.00101
selects the lines based on the value of their second field, which is referred to asyheptane
in your script. IDK the margin of error of your "0.1% of mass fraction" so I chose convenient conditions for the sample output below.
With the sample data, the output will be:
Time Length Mass
0.0001500 0.0895768 0.00100839
0.0002000 0.102057 0.00100301
0.0002000 0.0877939 0.00100832
0.0003500 0.0827694 0.00100114
0.0009000 0.0657509 0.00100015
0.0015000 0.0501911 0.00100016
0.0016500 0.0469495 0.00100594
0.0018000 0.0436538 0.00100853
0.0021500 0.0369005 0.00100809
0.0023000 0.100328 0.00100751
As an aside, here's a script for replacing your original code:
#!/bin/bash
set -- postProcessing/singleGraphVapPen/*/*
if ! [ -f VapPen.txt ]
then
{
printf '%s\t%s\n' 'Time [s]' 'VapPen [m]'
awk '
BEGIN {FS = OFS = "\t"}
FNR == 1 {
if (NR > 1)
print time,vappen
vappen = 0
n = split(FILENAME,path,"/")
time = sprintf("%0.7f",path[n-1])
}
NF != 2 {next}
$2 >= 0.001 { vappen = $1 }
END { if (NR) print time,vappen }
' "$@" |
sort -n -k1,1
} > VapPen.txt
fi
gnuplot -e '
set title "Verdunstungspenetration";
set xlabel "Zeit [s]";
set ylabel "Verdunstungspenetrationslänge [m]";
set grid;
plot "VapPen.txt" using 1:2 with linespoints title "Vapor penetraion 0,1% mass";
pause -1 "Hit return to continue";
'
With the provided data, it reduces the execution time from several minutes to 0.15s on my computer.
Answered By - Fravadona Answer Checked By - Katrina (WPSolving Volunteer)