Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running vi within a bash script and executing vi commands to edit another file

So I've made a script which is collecting data from many different files:

#!/bin/bash

mkdir DATAPOOL"$1"

grep achi *out>runner
grep treat *out>>runner

cat runner | grep Primitive *gout | grep '=   '|awk '{print $1,$6}' > CellVolume"$1".txt 
cat runner | grep ' c ' *gout | grep 'Angstrom   '|awk '{print $1,$3}' > Cellc"$1".txt 
cat runner | grep 'Final energy ' *gout |awk '{print $1,$5}' > CellEnergy"$1".txt

etc etc

cat runner |awk '{print "~/xtlanal",$1," > ",$1}' >runner2
vi runner2
:1,$s/gout:/xtl/
:1,$s/gout:/dat/
:wq

source runner2

grep Summary *dat | grep 'CAT-O  ' |awk '{print $1,$6}' > AVE_NaO_"$1".txt

mv *txt DATAPOOL"$1"

So I end up with all the required text files when run without the vi part and so I know it all works. Furthermore when I run it with the vi commands, it just stops running at the vi command and then i can manually enter the 3 commands and I end up with the correct results. What I'm struggling with is I cant get vi to run the commands on its own so I can just execute the file multiple times within different directories and not have to manually enter commands time and time again.

Any help would be greatly appreciated.

Cheers

like image 830
JJw Avatar asked Feb 25 '14 12:02

JJw


3 Answers

something like this as a bash script:

#!/bin/bash
vi filename.txt -c ':g/^/m0' -c ':wq'

where -c execute a command. Here the command is to reverse the lines in a textfile. After done, :wq to save and exit. (man vi to get more about -c)

If you don't want to type -c twice, you can do it this way:

vi -c "g/^/m0 | wq" filename.txt
like image 132
B.Kocis Avatar answered Oct 21 '22 18:10

B.Kocis


For scripted editing tasks, you can use ed instead of vi:

ed runner2 <<'END'
1,$s/gout:/xtl/
1,$s/gout:/dat/
w
q
END

For global line-oriented search and replace, sed is a good choice:

sed -i 's/gout:/xtl/; s/gout:/dat/' runner2
like image 24
glenn jackman Avatar answered Oct 21 '22 19:10

glenn jackman


Tested on VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Apr 10 2018 21:31:58)

The vi -c "g/^/m0 | wq" filename.txt may appear to work, but it does not actually!

Typing vi -c "g/^/m0 | wq" filename.txt will result in vi writing and quitting before any major changes are made to the file. (using the pipe in this situation will attempt to execute the wq line by line forcing it to quit before the intended operation)

In order to see a demonstration try typing it without the q and see how slow it works writing line by line:

vi -c "g/^/m0 | w" filename.txt

The more efficient way is using -c as B. Kocis states, or use +.

As B. Kocis stated:

#!/bin/bash
vi filename.txt -c ':g/^/m0' -c ':wq'

or

vi filename.txt +g/^/m0 +wq
like image 23
mOmOney Avatar answered Oct 21 '22 17:10

mOmOney