Compare two folders for differences


-a treats all files as text, -r recursively searched subdirectories, -q reports 'briefly', only when files differ

diff -arq folder1 folder2

pushd popd dirs

# push a directory onto the stack
pushd {dir}
# pop the last directory off the stack, change to the next directory in the stack
# view the stack in a numbered list
dirs -v 
# pull the nth directory out of the stack, put it at the top, and change to it
pushd +n
# remove the nth directory from the stack, don't change to it or anything
popd +n

Saving command line history


Alan Schussman asks "Is there a word for when you have to reboot for software updates, but have a ton of terminal tabs with a month’s work of personal project history in them that maybe, just maybe I’ll need someday?"

To which I say, "Frustrating."

I have these two bash functions to save and find commands I've run (yes, I have a history going back a large number of years).

$ hsave to save history.
$ sg COMMAND to find how I ran that command before.

Add it to the ~/.bash_logout script, and the terminal's history should save when you close a terminal. I have a large history buffer. As such, I do have a lot of duplicate commands across multiple saved history files. Having 4 windows open all the time doesn't help with that overlapping history either.

function hsave(){
  history >> ~/work/projects/sweep/history-`date +'%Y%m%d%H%i%s'`$1.txt
function sg(){
  grep -ir $1 ~/work/projects/sweep

bash for loop


Because you need a loop when you're not in tcsh.

for fn in `cat filenames.txt`; do
    echo "the next file is $fn"
    cat $fn
# my one-liner
for f in `ls *JPG`; do echo $f; $f; done

Determine bash script's location from bash script


Sometimes, you need to know the current (full-path) directory of a bash script in order to launch another file relative to the bash script, instead of using global paths or the $PATH value.

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Replace all string matches from previous command in bash


$ !!:gs/replacethis/withthis/

gs = global replace

Works only with bash version 3 or greater:

bash-3.2$ bash --version 
GNU bash, version 3.2.57
$ echo oneone
$ !!:gs/one/two/    # Repeats last command; substitutes 'one' --> 'two'.

Move a series of images into directories matching the image names


I had a series of files (*.png) that I wanted moved into individual directories of the same name, sans extension.

# one line
for f in *png; do fn=$(basename $f); d="${fn%.*}"; echo $d; mkdir $d; mv $f $d; done
# Expanded with explanations
# list of files
for f in *png; do
  # get the file name without the path
  fn=$(basename $f); 
  # get just the filename root, without the extension
  # output to screen so that we know something is going on
  echo $d
  # make the directory
  mkdir $d
  # move the file into the directory
  mv $f $d
# close the loop

bash notes


Notes on bash

# length of a variable
# confirming the length
$ echo $size
# => 11
# use in an if statement
if [ ${#size} < 4 ]; then
  echo "mystr can't be fewer than 4 characters"
if [[ $barf ]] then; 
if [[ ! $id ]]; then
  echo "doesn't exist"
  echo "exists. $id"

redirect stderr to stdout


setting up bash aliases


edit the .bashrc and add these lines

alias d='dirs -v'
alias hg='history | grep $1'
alias pu=pushd
alias psg='ps -ef | grep $1'
alias purge='rm *~'
alias svndiff='svn diff --diff-cmd=`which diff` -x -w $1'
export HISTFILESIZE=3000
umask 002