The file myfile.out contains a series of digits. The purpose is subtract 1st number from 2nd number(2nd-1st),3rd number minus 2nd number and so on
$ cat myfile.out
10
30
5
802
96
i.e
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d' | tac | paste -sd"- " | tr ' ' '\n' | tac | sed -e 's/-/ & /' -e 's/[0-9].* - .[0-9]*/echo `expr &`/'
echo `expr 30 - 10`
echo `expr 5 - 30`
echo `expr 802 - 5`
echo `expr 96 - 802`
The breakdown in each of the pipes:
Adding a duplicate of each digit
$ sed -e 's/[0-9]*/&\n&/' myfile.out
10
10
30
30
5
5
802
802
96
96
Deleting 1st and last line
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d'
10
30
30
5
5
802
802
96
Reversing
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d' | tac
96
802
802
5
5
30
30
10
Making the format using "paste" command
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d' | tac | paste -sd"- "
96-802 802-5 5-30 30-10
Replacing each space with newline
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d' | tac | paste -sd"- " | tr ' ' '\n'
96-802
802-5
5-30
30-10
Again reversing
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d' | tac | paste -sd"- " | tr ' ' '\n' | tac
30-10
5-30
802-5
96-802
Formating
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d' | tac | paste -sd"- " | tr ' ' '\n' | tac | sed -e 's/-/ & /' -e 's/[0-9].* - .[0-9]*/echo `expr &`/'
echo `expr 30 - 10`
echo `expr 5 - 30`
echo `expr 802 - 5`
echo `expr 96 - 802`
Now
$ sed -e 's/[0-9]*/&\n&/' myfile.out | sed -e '1d' -e '$d' | tac | paste -sd"- " | tr ' ' '\n' | tac | sed -e 's/-/ & /' -e 's/[0-9].* - .[0-9]*/echo `expr &`/' > myfile1.out
Executing myfile1.out
$ sh myfile1
20
-25
797
-706
ohh! it was a long one liner, good to learn the uses of different sed operations. The same can be achieved in a very traditional way:
FILE=./myfile.out
N=1
total=`sed -n '$=' $FILE`
until [ "$N" -eq $total ]
do
S1=$N
S2=`expr $N + 1`
N=$S2
VAL1=`sed -n "$S1 p" $FILE`
VAL2=`sed -n "$S2 p" $FILE`
expr $VAL2 - $VAL1
done
Sunday, February 17, 2008
Sequence subtration, one liner
Subscribe to:
Post Comments (Atom)
© Jadu Saikia www.UNIXCL.com
2 comments:
that was quite ingenious...very well done...Your explanations are exceptionally clear and very approachable.
I am a neophyte when it comes to shell programming and domain specific languages like paste/AWK/SED/M4. I really appreciate the unique and interesting examples
sed -e '
$!N;h;s/\(.*\)\n\(.*\)/\2\n\1/;s/\n/-/p;g;D
' < myfile1.out | bc -l
perl -lne '
print $_ - $p if $. > 1;
$p = $_;
' myfile1.out
Post a Comment