bash script for gnuplot input - bash

I am using the following lines in a script.
foo=$1
bar=$(printf ' , "%s" u ($1):($2) lw 8 ti' ${foo[#]} ${foo[#]} ${foo[#]} ${foo[#]} )
bar=${bar:2}
echo $bar
This produces the following line as the value of variable bar
"rdf_inter_fortran_05-25.xvg" u ($1):($2) lw 8 ti , "rdf_inter_fortran_05-25.xvg" u ($1):($2) lw 8 ti , "rdf_inter_fortran_05-25.xvg" u ($1):($2) lw 8 ti , "rdf_inter_fortran_05-25.xvg" u ($1):($2) lw 8 ti
Is it possible to modify the script so the output is:
"rdf_inter_fortran_05-25.xvg" u ($1):($2) lw 8 ti , "rdf_inter_fortran_05-25.xvg" u ($1):($3) lw 8 ti , "rdf_inter_fortran_05-25.xvg" u ($1):($4) lw 8 ti , "rdf_inter_fortran_05-25.xvg" u ($1):($5) lw 8 ti

Change your printf line to the following :
bar=$(printf ' , "%s" u ($1):($%s) lw 8 ti' ${foo[#]} "2" ${foo[#]} "3" ${foo[#]} "4" ${foo[#]} "5" )

It looks like you are replacing some $2's with new strings. Insert this line before echo $bar :
bar=$(echo $bar | sed 's/$2/$5/4; s/$2/$4/3; s/$2/$3/2;')
This replaces the 4th, 3rd and 2nd occurrence of $2 with new respective values $5, $4 and $3.

Related

Gnuplot script error "invalid expression"

Below is the code meant to output successive images for a gif file:
for i in {1..600}
do
python Phy_asg.py $i
gnuplot <<- EOF
unset tics;unset key;unset border
set xrange [-15:15]
set yrange [-15:15]
set arrow 1 from 0.012*$i,cos(0.012*$i)-pi to sin(0.024*$i),cos(0.012*$i ) nohead ls 8 lw 2
set arrow 2 from sin(0.024*$i)+pi,0.012*$i to sin(0.024*$i),cos(0.012*$i ) nohead ls 8 lw 2
plot "< seq -9 .2 -3.1" u (cos(2*$1)):($1) with lines
replot "< seq -9 .2 -3.1" u ($1):(cos(2*$1)) with lines
replot "data_asg.txt" with lines lt 22 lw 2
set terminal png size 512,512
set output "Phy_gif_$i.png"
replot
EOF
done
Here the Phy_asg.py is python script to produce data in form of text file and its name is data_asg.txt. The shell gives me error in the line 10. It says:
gnuplot> plot "< seq -9 .2 -3.1" u (cos(2*)):() with lines
^
line 0: invalid expression
I am not able to figure out the problem. Is it with the seq command or formatting error.
The $1 is interpreted as shell parameter instead of data column. Either escape the dollar, \$1 or use column(1), I prefer latter
for i in {1..600}
do
python Phy_asg.py $i
gnuplot <<- EOF
set terminal png size 512,512
set output "Phy_gif_$i.png"
unset tics;unset key;unset border
set xrange [-15:15]
set yrange [-15:15]
set arrow 1 from 0.012*$i,cos(0.012*$i)-pi to sin(0.024*$i),cos(0.012*$i ) nohead ls 8 lw 2
set arrow 2 from sin(0.024*$i)+pi,0.012*$i to sin(0.024*$i),cos(0.012*$i ) nohead ls 8 lw 2
set style data lines
plot "< seq -9 .2 -3.1" u (cos(2*column(1) )):1, \
"< seq -9 .2 -3.1" u 1:(cos(2*column(1))), \
"data_asg.txt" lt 22 lw 2
EOF
done

apply a command to the values of a column in a text file and replace

cat file
1 a GYPA
2 b GYPA 002099.7:c.59
2 c GYPA 002099.7:c.71
2 d GYPA 002099.7:c.72
3 e GYPA 002099.7:c.59
4 f GYPA 002099.7:c.140
5 g GYPA 002099.7:c.68
I have the following file I am processing. I would like to replace the fourth column with the output of command <options> $4 as follows:
EXPECTED OUTPUT
1 a GYPA
2 b GYPA out1
2 c GYPA out2
2 d GYPA out3
3 e GYPA out4
4 f GYPA out5
5 g GYPA out6
where out1 is cmd <opts> '002099.7:c.59'
This gets very complicated with awk since I need to use quotes '002099.7:c.59' to wrap the text.
I have been using:
t="\t"
while read -r a b c d
echo -e $a$t$b$t$c$t$(cmd opt $d);
done
When the 4th column entry is empty (i.e. first line), I get an error output from cmd <opts>. Is there a simpler alternative to this where I could use column number besides awk?
while IFS=$'\t' read -r col1 col2 col3 col4; do
if [ -n "$col4" ]; then
col4=$(yourcommand "$col4")
printf '%s\t%s\t%s\t%s\n' "$col1" "$col2" "$col3" "$col4"
else
printf '%s\t%s\t%s\n' "$col1" "$col2" "$col3"
fi
done

Shell-Script to join all CSV files in directory with two key-columns

I'm struggling for a while now.
I have a directory with more than 5 CSV files. The idea is to join them all with a script (maybe with a loop?).
Example with only two files:
File1
1 ; 1.1 ; xyz
1 ; 1.2 ; abc
2 ; 2.1 ; gfa
File2
1 ; 1.1 ; dft
1 ; 1.2 ; asd
2 ; 2.1 ; qwe
Output file should look like this:
1 ; 1.1 ; xyz ; dft
1 ; 1.2 ; abc ; asd
2 ; 2.1 ; gfa ; qwe
In every CSV file, the first two columns are the "primary-key". I have tried it with join and awk but I don't get it (wrong approach?).
Thanks for the help.
Input files:
$ cat featureA
SW1 ; 1.1 ; xyz
SW1 ; 1.2 ; abc
SW2 ; 2.1 ; gfa
$ cat featureB
SW1 ; 1.1 ; dft
SW1 ; 1.2 ; asd
SW2 ; 2.1 ; qwe
Output:
awk 'BEGIN{FS=OFS=";"}{k=$1 OFS $2}FNR==NR{arr[k]=$3;next}k in arr{print k,arr[k],$3}' featureA featureB
SW1 ; 1.1 ; xyz; dft
SW1 ; 1.2 ; abc; asd
SW2 ; 2.1 ; gfa; qwe
To address
I have a directory with more than 5 CSV files. The idea is to put
several CSV in this directory and run a script to join them all (maybe
with a loop?). The files are about switches.
$ awk 'BEGIN{FS=OFS=";"}{k=$1 OFS $2}{arr[k]=(k in arr?arr[k] OFS:"")$3}END{for(i in arr)print i, arr[i]}' feature*
SW1 ; 1.1 ; xyz; dft
SW1 ; 1.2 ; abc; asd
SW2 ; 2.1 ; gfa; qwe
Explanation:
awk 'BEGIN{
FS=OFS=";" # i/p and o/p field separators
}
{
k=$1 OFS $2 # variable k used as key,
# field1 o/p field sep and field2
}
FNR==NR{ # read featureA file
arr[k]=$3; # save 3rd field in array arr, with key being variable k
next # go to next
}
k in arr{ # read featureB file, if key exists in array arr
print k,arr[k],$3 # print k, array value, and 3rd field
}
' featureA featureB

Bash Pipe Multiple Lines into Gnuplot

I have the code,
echo "set term postscript" |
echo "set output 'output.ps'" |
for FILE in output*; do
echo "plot '${FILE}' u 1:2 w l t '1', '${FILE}' u 1:3 w l t '2', '${FILE}' u 1:4 w l t '3'"
done | gnuplot -persist
I want the first two lines to be printed before anything else inside gnuplot. How can I achieve this?
Best,
Jacob
Do I understand correctly that you are trying to "group" the first three commands and pipe their collective output into gnuplot? If so, you can write:
{
echo "set term postscript"
echo "set output 'output.ps'"
for FILE in output* ; do
echo "plot '${FILE}' u 1:2 w l t '1', '${FILE}' u 1:3 w l t '2', '${FILE}' u 1:4 w l t '3'"
done
} | gnuplot -persist
Edited to add: Incidentally, you might find it more readable to break up your third echo across multiple lines:
echo plot "'${FILE}' u 1:2 w l t '1'," \
"'${FILE}' u 1:3 w l t '2'," \
"'${FILE}' u 1:4 w l t '3'"
(echo joins its arguments with spaces, so this is equivalent to the previous. It's totally up to you which version you find easier to work with.)

Moving columns from the back of a file to the front

I have a file with a very large number of columns (basically several thousand sets of threes) with three special columns (Chr and Position and Name) at the end.
I want to move these final three columns to the front of the file, so that that columns become Name Chr Position and then the file continues with the trios.
I think this might be possible with awk, but I don't know enough about how awk works to do it!
Sample input:
Gene1.GType Gene1.X Gene1.Y ....ending in GeneN.Y Chr Position Name
Desired Output:
Name Chr Position (Gene1.GType Gene1.X Gene1.Y ) x n samples
I think the below example does more or less what you want.
$ cat file
A B C D E F G Chr Position Name
1 2 3 4 5 6 7 8 9 10
$ cat process.awk
{
printf $(NF-2)" "$(NF-1)" "$NF
for( i=1; i<NF-2; i++)
{
printf " "$i
}
print " "
}
$ awk -f process.awk file
Chr Position Name A B C D E F G
8 9 10 1 2 3 4 5 6 7
NF in awk denotes the number of field on a row.
one liner:
awk '{ Chr=$(NF-2) ; Position=$(NF-1) ; Name=$NF ; $(NF-2)=$(NF-1)=$NF="" ; print Name, Chr, Position, $0 }' file

Resources