VIM and Solving a More Complex Lower-case'ing
Submitted by Steve on May 9, 2007 - 8:04pm.
The problem was looking painful.
I needed to lower case parts of about 130 lines of code. But only part of each given line. tr and/or sed are my normal tools of choice for such a beastie, but I wasn't sure I could convince either to only hit the section I wanted.
Basically, I had:
const char *kwords[] = { "Undefined", /* 0 = undefined keyword 0 */
"OutputDir", /* Output directory 1 */
"LogFile", /* Log file to use for input 2 */
"ReportTitle", /* Title for reports 3 */
"HostName", /* Hostname to use 4 */
...
and wanted:
const char *kwords[] = { "undefined", /* 0 = undefined keyword 0 */
"outputdir", /* Output directory 1 */
"logfile", /* Log file to use for input 2 */
"reporttitle", /* Title for reports 3 */
"hostname", /* Hostname to use 4 */
...
Tricky. Or so I initially thought. I'd just about resigned myself to 15 minutes of terminal boredom manually editing this when my quick reading of the vim help (:help replace) led me to being able to construct this relatively simple one liner fix:
:'a,'bs/"\([A-Za-z0-9]*\)"/"\L\1\E"/
Or in English:
- Preparation: Mark a & b, being the start and end you wish to process.
- So: From Mark a ('a) to Mark b ('b) do a search and replace
- Search for A-Z, a-z and 0-9 characters, alnum's basically, enclosed in double quotes. Keeping track of the text in the quotes ( \(...\) )
- Replace with the double quotes we found. &
- Lower-case (\L) the found text (\1) only (\E - delimits the end of \L)
Too Easy.
Incidentally, this also means I've managed to somewhat simply implement case insensitivity into the AWFFull config file processing. At long last. Hurrah! 


