# zigford.org

About | Links | Scripts
Sharing linux/windows scripts and tips

### Vim Odd Jobs 1

March 30, 2019 — Jesse Harris

Today Clarissa did the shopping and as she was in a rush didn't have the time to total the items in the trolley. She had updated the cost of each item in a shared iCloud note and texted me to see if I could quickly add them up on my computer.

This is the point where most people would pull out `calc.exe` and manually sum them. Not I!.

I fired up the iCloud site on my machine and copy and pasted the iCloud note to a fresh vim buffer:

        Shopping 2019
        1st Isle:
        Vedge
        Potatoes 4 + 6 6 3 3 5 16.99 2 2 3 3 4.99 5.99 5.99 5.99 12.15 7.99 7.99 8.99
        Other vedge for a meat + vedge dinner
        Meats
        Chicken dinner with a sauce (Indian or Apricot or some other chicken + rice meal)
        Lunch Chicken
        Sausages
        Kids Junk Food
        Tiny Teddies (Olivia’s request) 2.49 2.49
        Flavoured Rice Cakes 6
        Crackers 2.49 2.49
        Dairy 2.69
        Big tub of greek yogurt
        Vanilla Bean Yogurt 3.99 3.99 3.99
        Butter  - 4.99 4.99 4.99
        Milk Powder  - 5.69 5.69 5.69
        Second Isle
        Corn Chips for Nachos
        Nacho Salsa
        Popcorn 2.49 2.49 9.98
        A Cordial or somesuch 2.49
        Third Isle
        Frozen
        Pies 3.55 3
        Lasagne? 12
        French Fires 1.89 1.89
        Chicken Nuggets 2.99 2.99
        Cleaning
        Garbage Bags 1.79
        Mozzie Coils
        Last Isle
        Food
        Spaghetti Pasta .65 .65 1.59 1.59
        Tinned Beetroot 1.15
        Tinned Spagetti * .85 .85 .85
        Indian or rice meal sauce 2.49 .99
        Personal
        Soap 1.99 3.49
        Food
        Brown Sugar 2.69
        Bread 1.25 1.25
        Wraps 1.95 1.95
        2.99
        8.49
        1.99 1.99 1.99

My thought was this:

- Do a search and replace on everything bar the numbers
- Quickly tally the numbers using `bc`

### Step 1. Find the search

Best way to figure out a regular expression in vim is to enable these two settings:

        :set hlsearch incsearch

With these set, you can begin a search by typing `/` then as you type results are instantly highlighted.

After a few tries with negative lookbehinds and whatnot, I settled on this:

        /\v[a-zA-Z()+*?\- :]

The `\v` causes Vim to use a more modern regex pattern requiring far less escape characters.

### Run the search

I then ran the search of the whole file:

        :%s/\v[a-zA-Z()+*?\- :]/ /g

Then all I had to do was clean up double spaces and the blank lines

        :%s/\v^\s+//g    " removing leading spaces
        :g/\v^$/d        " delete blank lines

### Convert it to a format that bc would like

        :%s/\v\s/+/g     " replace spaces with +
        :%s/\v\n/+/g     " replace newlines with +
        :%s/\v\+$//g     " remove any trailing +'s

### Tally with BC

You can do this from within Vim using the `!` command or drop the shell and do it

        :!cat % | bc

Now all that may seem a little over the top for tallying a shopping list, however it's little exercises like this that can help you learn more vim, regex, shell and other useful things

#### Extra credit

You could of course you another tool to add the numbers up. Here is how to do it using `awk` having each number on a seperate line:

        :!awk '{n+=$1}; END{print n}' %

Using powershell each number on seperate line

        :!pwsh -com "&{gc %|\%{[double]\$n+=\$_};\$n}"

Credit for awk and bc goes to this askubuntu answer.

Tags: vim-tips, vim-odd-jobs