bash

pushd popd dirs

Snippet
# push a directory onto the stack
pushd {dir}
 
# pop the last directory off the stack, change to the next directory in the stack
popd 
 
# 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

Snippet

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

Snippet

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
done
 
# my one-liner
for f in `ls *JPG`; do echo $f; gallery-post.sh $f; done

Determine bash script's location from bash script

Snippet

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

Snippet

$ !!: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
oneone
$ !!:gs/one/two/    # Repeats last command; substitutes 'one' --> 'two'.
twotwo

Move a series of images into directories matching the image names

Snippet

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
  d="${fn%.*}"
 
  # 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
done

bash notes

Snippet

Notes on bash

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

redirect stderr to stdout

Snippet

setting up bash aliases

Snippet

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

bash for loop

Snippet

Loop over bash files

for file in $(ls *.mt1); do mv $file $file.txt; done;