a little vi trick
An update to my previous article My vi first steps
I use vi instead of command line editors to do mass replacing of blocks and editing many files in the following way:
say I know all files I need to edit in the current directory contain the text foo and the rest of the files don't.
I open all files containing foo in vi:
vi $(grep -l 'foo' *)
start macro recording to register q
search and replace in the whole file
/%s/foo/bar/g
next file
:wn
stop recording
q
execute the macro many times to be sure we got them all, if we get to the end vi will complain that it can't go beyond the last file.
200@q
This is obviously not the most efficient way of doing this particular replace, but you can imagine the time it saves when you don't need to dream up and test a complex regular expression because in vi you can do things like search for a pattern and replace one line beneath it. Or make several changes at once.
Little imagination is needed to come up with very complex changes to lots of files with a little knowledge of vi, while keeping your sanity.
Like this one:
Keeping macros available between sessions is needed for this one. Add this line to your ~/.vimrc file:
set viminfo=%,'50,\"100,n~/.viminfo
unless something like this is already there of course.
100 saves the first 100 lines of each register in the viminfo file. Making it available for all future sessions until you overwrite it.
or use the marvin vim plugin:
http://www.vim.org/scripts/script.php?script_id=2154
Now you can easily run vimdiff on two files if you have one containing the block of text you want to put in all the other files.
vimdiff file1 file2
This opens the two files in comparison mode in vim file1 on the left file2 on the right.
Navigate to the block you want to use. Differences are highlighted so it's easy to find. Now switch screens with CTRL-w,CTRL-w (that's CTRL-w twice) and copy the lines or words or block you need.
To get a block:
Go to the start of your block and press v for visual mode.
Go to the end of the block and press y for yank.
quit the files with :x (twice)
The rest is the same as before, just open multiple files with vi * or vi $(grep -l 'pattern' *)
And record a macro which deletes the content you want replaced and paste the current buffer(recorded in the previous session) using the p in it's place.
Or you can already record the macro in the first opened files, just close the file you don't want to edit using :x and record the macro replacing the buffered text at once. The macro and the buffer will both be available across settings.
Thanks to Linuxoneliner.com for the code to open all files containing pattern in vi.
Am I doing things overly complex? Do you know a better way of doing this? Have more creative things we can do with vi? Leave a comment! Comments can take a while before they get published (other time zone)
Popular content
Recent blog posts
- HP linux netbook
- Toshiba Android netbook
- android video terminal
- rugged android phone
- Linux PC Robot < 500$ DIY Linux robot
- Q7 Linux MID nice but missing most important feature
- BD remote for android available soon
- Intelligent Linux based scriptable network camera
- Edge the first foldable dual screen ebook reader/netbook
- iPed chinese for iPad
don't forget to vote if you find something useful!!
- Hm
43 weeks 3 days ago - What is it called?
44 weeks 23 hours ago - i done everything . when i
47 weeks 3 hours ago - 11. Be logged in with more
49 weeks 4 days ago - Additions to computer user
49 weeks 4 days ago - Source code Philips tv
49 weeks 5 days ago - philps 5604 source code
49 weeks 5 days ago - Getting a error ___Main__.PY error any ideas?
1 year 1 week ago - Meh....
1 year 3 weeks ago - not the smallest
1 year 3 weeks ago
Navigation
Arduino starter kit
nederlandse arduino tutorials

Smallest Linux PC, smaller
than an apple

Linux home automation

Electrical superbike
powered by Linux

Coolest Linux robot ever
transforming,camera,
remote control

Samsung tv Linux hack

Linux multimedia
dream machine

More cool stuff
like this solid gold macbook
at criticalcold.com
Tags
Best karma users
- mr-Z
- Ian_js
- dave-d
- gamer2k2
- links9
Categories



use perl;
Anonymous 2 years 41 weeks 21 min 26 sec ago
perl -i -pe 's/foo/bar/g' `grep -l foo *`
or if you prefer to replace recursively:
find . -type f -exec grep -l foo "{}" \; | cut -d: -f1 | xargs perl -i -pe 's/foo/bar/g'
Sed
Anonymous 2 years 41 weeks 2 hours 12 min ago
sed 's/foo/bar/g' *
use sed
Anonymous 2 years 41 weeks 1 day 38 min ago
Not tested, but I'd do something like this:
sed -i "s/foo/bar/g" `grep -l foo *`
The "grep -l" in the backquotes returns a list of filenames.
"sed -i" edits files in place.
very nice! but the Unix's
Anonymous 2 years 41 weeks 4 hours 37 min ago
very nice!
but the Unix's sed has not -i option :(
regards!
you can also do something
Anonymous 2 years 41 weeks 1 day 3 hours ago
you can also do something like:
for i in *foo*; do
echo -e "% s/foo/bar/g\nwq\n"|ed $i
done
Note: not tested :)
bufdo
Anonymous 2 years 41 weeks 1 day 8 hours ago
Hi,
for your first trick, you can use bufdo to run a command on all open buffers. So,
":bufdo! %s/foo/bar/g"
when vim opens the files will work just as well