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
> 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:
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 ~ ~
:r followed by exclamation mark and
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:
Use regular expressions to prepare shell command
Now I want to generate copy commands for shell. In vim execute
:%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
To summarize it:
- Execute on the whole file - range
- 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:
- Followed by the whole original line -
\1references 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
\2in replace part
- Followed by the string
201that replaces the original
- Followed by the rest of the matched line -
- Command flags:
g- global, execute the substitute command repeatedly on the line - not important here because I'm matching the whole line
c- 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
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:
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
> 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.