Monday, August 13, 2012

vi/bash Miscellanea

Today I discovered and exercised a bunch of great things about vi and bash. To celebrate, I will write the most memorable ones here. First vi:
  1. :% - Indicates to execute a command across the range of all lines. It has helped me greatly in my quick file-wide substitutions.
  2. Recording commands: Press q, then any other letter that will identify the custom command, like a. Then perform the exact sequence of commands, insertions, deletions, modifications you want to record, then press q again. Now you have a recorded command!! Press @a (or whichever letter you chose as the command identifier) to execute this sequence of commands again. Or do it many times with N@a!
  3. You can cut/copy/paste not only lines but words and characters in vi. For example, cut the next 7 characters with 7d[RIGHTARROW]. Or copy the current word with yw. And if you have less than entire lines selected, pasting stays in the same line (I used to only cut/copy/paste entire lines in vi).
  4. Redo with Ctrl-r (for those hasty undos!)
  5. Awesome little "up-arrow"-style previous-command recoverers. To see the last vi command you executed: ":[UP-ARROW]". (And navigate with up-arrow and down-arrow, like in bash or in MATLAB). To see the last search string you looked for: "/[UP-ARROW]". To see a list of possible undo's in your file, execute ":undolist". (I haven't actually tried that last one, but it seems too useful to not write).
And now for bash:

  1. I found a way to exercise that the length of a string variable can be obtained through ${#f}, and that the length of an array can be obtained through ${#f[@]}.
  2. I also exercised with bash arrays: define -a arrVariable=($(ls -all)). Notice the parentheses around whatever you're trying to initialize the array with. I believe the string is split and nicely put into the array using the default IFS (internal file separator) delimiter.
  3. I also found an awesome little tool called bc that makes up for the lack of non-integer arithmetic in bash. Basically, this command $(bc <<< "scale=9; $x/5.7") outputs the result of whatever x was divided by 5.7 with 9-significant-digit precision (I think). It's not exactly a built-in solution, but I think it complements bash's capabilities very appropriately. It really hits the spot. I see it like an adjunct floating-point co-processor for bash. It's great! (Notice the <<<, it'll be explained soon).
  4. I also discovered you can identify streams in this manner: 3 < filename. I'm still not entirely certain how input streams are handled, but at least now I know that I can identify them neatly inside bash scripts.
  5. Also, I learned about the triple redirector operator!! (<<<). It's great! For example, before when I wanted to do something like:
while read line
do
    blah
    blah
    moreBlah
done < filename

filename HAD to be an actual filename - it could not be the ad-hoc result of a quick command obtained on the fly. So sometimes weird hacks had to be made to adapt a quick command result into a file stream. But today I learned that if you replace the last line by 

done <<< $(command here, such as ls -all)

it will now work! I often wondered how to bridge that gap between file streams and ad-hoc input streams. Well, this helps a lot to make that happen!

And... that's it. I'm gonna go home because it's past 11PM and I'm still in the office. Bye...

No comments:

Post a Comment