I have been using vim almost exclusively for file editing on any operating system that I use, whether Mac OS X, Linux or Windows. Here is an example how to use vim to build and execute bash commands using vim's regular expressions.
Often I manipulate log and data files. I need to copy a group of files. Each file in the group have date stamp and I need to make copies with different date stamps.
Here is how you can create bash commands to copy group of files from vim.
My directory contains four files and a directory called abc
:
> ls abc abc.4.0.20100204.body abc.4.0.20100204.header abc.4.0.20100204.seqnums abc.4.0.20100204.session
I need to create a copy of the whole group of files with timestamp of 20100201, bash command looks like this:
mv abc.4.0.20100204.body abc.4.0.20100201.body ...
Load output of external command to vim
In the directory open vim and load up list of files:
:r!ls *.*
The vim window will have the list of files displayed:
abc.4.0.20100204.body abc.4.0.20100204.header abc.4.0.20100204.seqnums abc.4.0.20100204.session ~ ~
This is read
command :r
followed by exclamation mark and command
.
It executes the external command in shell and inserts its standard input into vim. In this case I want to get a list
of files but not the directory abc
so I use:
ls *.*
Use regular expressions to prepare shell command
Now I want to generate copy commands for shell. In vim execute substitute
command:
:%s/\(\(.*\)204\(.*\)\)$/cp \1 \2201\3/gc
You get asked if you want to execute each substitution, just press y
, this is because of the c
- confirm flag.
This is a substitute
command:
<range>s/pattern/replace/options
To summarize it:
- Execute on the whole file - range
%
- Substitute
s
- Brackets are for remembering matched contents, they get numbered from left to right later referenced in replace
- Match anything up to 204 (part of time stamp in file name), I want to update the timestamp
- Match everything after the timestamp
- Replace the matched line with:
cp
- Followed by the whole original line -
\1
references the first bracket that matches everything up to end of the line in the original line. - Followed by the first part of filename up to
204
- stored by second group of brackets and reference by\2
in replace part - Followed by the string
201
that replaces the original204
string - Followed by the rest of the matched line -
\3
- Command flags:
g
- global, execute the substitute command repeatedly on the line - not important here because I'm matching the whole linec
- confirm before replacement
The vim window now looks like this:
cp abc.4.0.20100204.body abc.4.0.20100201.body cp abc.4.0.20100204.header abc.4.0.20100201.header cp abc.4.0.20100204.seqnums abc.4.0.20100201.seqnums cp abc.4.0.20100204.session abc.4.0.20100201.session ~ ~
Execute bash commands from vim
To execute bash
commands in the current directory, first highlight the lines with Ctrl-v
and down/up to highlight all commands. Now enter :
to start typing the rest of the command. This will insert the range '<,'>
signifying the highlighted lines. Type the rest of the command:
:'<,'>!bash
This executes commands in highlighted lines in bash. Quit vim and check the directory. You have copied files with 20100204
date stamp to the ones with 20100401
:
> ls abc abc.4.0.20100201.header abc.4.0.20100201.session abc.4.0.20100204.header abc.4.0.20100204.session abc.4.0.20100201.body abc.4.0.20100201.seqnums abc.4.0.20100204.body abc.4.0.20100204.seqnums
I have loaded output of external bash command into vim, used vim's regular expressions to generate commands, then executed the commands in bash directly from vim.
No comments:
Post a Comment