ilter for Unique Lines Adjacent or Otherwise While Preserving Original Order

There are two BASH utilities that help you filter input for unique lines: ‘uniq’ and ‘sort‘: One gotcha with ‘uniq’ is that it only filters out duplicate adjacent lines. So if your input looks like: apple apple apple chicory chicory chicory banana banana Then running ‘uniq’ on it will yield: apple chicory banana But if the input has non-adjacent duplicate lines: apple banana banana chicory apple banana chicory banana banana apple apple apple banana chicory Then the results are:

Read more

Filesystem Management with the Full Power of Vim

Just discovered “vidir“, a way to manipulate filenames inside your favorite text editor (better known as Vim). Previously, I would use complex and cumbersome BASH constructs using “for;do;done”, “sed”, “awk” etc., coupled with the operation itself: $ for f in *.txt; do mv $f $(echo $f | sed -e 's/foo\(\d\+\)_\(.*\)\.txt/bar_\1_blah_\2.txt/'); done Which almost always involved a “pre-flight” dummy run to make sure the reg-ex’s were correct: $ for f in *.

Read more

Editing Remote Files With Your Local Vim Using the SCP Protocol

I love Vim! It is so easy enough to edit a remote file with my local Vim through the Secure Copy protocol: $ vi scp://user@remote.host.com/projects/foo/bar.py However, I often find myself wishing that bash completion was available to expand/complete paths on the remote system. Furthermore, when editing files outside of my home directory hierarchy, I have to remember to add an extra slash after the host name, e.g.: $ vi scp://user@remote.host.com//var/www/html/index.htm A solution is to write a custom wrapper function that takes scp-style remote file paths, converts them into Vim-style remote file paths, and then invokes Vim on them.

Read more

Easily Create Clean Compressed Tarballs of Your Git Repository

Ideally, you could refer the whole world — or at least, the significant portion thereof that want your code — to your (public mirror) Git repository. But unfortunately, the whole world does not (yet) use Git (“I know it was you Fredo, I know it was you, and it breaks my heart.“). Sad. Sooooo sad. But true. So the only recourse is for you to send these tortured souls an archived snapshot of your code via e-mail.

Read more

Boosting Interactive Bash Efficiency Through History Search Completion Editing

Most of us know about using the bang operator (!) to recall an entry from our bash history: $ ! # repeat last command $ !22 # repeat command 22 You can use “!:” followed by a number to substitute in arguments from previous commands. So, for example, to run the command “dosomething” on the first argument of the previous command: $ dosomething !:1 The fc command is also very useful, opening up the default editor to let you edit previous commands.

Read more

Dealing with 'Argument list too long' Problems

The solution to this problem is to the “Argument list too long“ error when trying to archive a large number of files is the “-T“ option of the “tar” command to pass in a list files generated by a “find” command: Create a list of the files to be archived using the “find“ command: $ find . -name="*.tre" > filelist.txt Use the “-T” option of the “tar” command to pass in this list of filenames:

Read more

Add the Following Lines to Your `~/.bashrc` and You Will Be Very Happy

I added the following to my ~/.bashrc and I am loving it! ## Up Arrow: search and complete from previous history bind '"\eOA": history-search-backward' ## alternate, if the above does not work for you: #bind '"\e[A":history-search-backward' ## Down Arrow: search and complete from next history bind '"\eOB": history-search-forward' ## alternate, if the above does not work for you: #bind '"\e[B":history-search-forward' (see the comments below for explanation of the alternate codes) The first command rebinds the up arrow from “previous-history”, which unconditionally selects the immediately preceding command from your command history, with “history-search-backward”, which selects the previous command in your history that begins with the characters you have already typed in.

Read more