131 lines
3.6 KiB
Markdown
131 lines
3.6 KiB
Markdown
Vim Odd Jobs 1
|
||
|
||
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`][1]
|
||
|
||
### 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][2] answer.
|
||
|
||
Tags: vim-tips, vim-odd-jobs
|
||
|
||
[1]:https://www.gnu.org/software/bc/manual/html_mono/bc.html
|
||
[2]:https://askubuntu.com/questions/785038/how-can-i-sum-numbers-on-lines-in-a-file
|