[bash] Directory stack and tilde expansion

Tags

, , , , , , , , , ,

First, some basics about directory stack:

1. Show directory stack with indices:
$ dirs -v
The top directory, i.e. the one with index=0, is the current working directory. On the other hand,
$ dirs [-N | +N]
where -N (+N) will show the Nth directory from bottom (top) where the entry at bottom (top) has index=0.

2. Add a directory, dir, to the stack
$ pushd -n dir
which puts dir (index=1) just below the current working directory (index=0) but above all others in the stack. If the -n is missing, pushd will change the working directory to dir thus causing dir to have index 0 and all other directories to be pushed down the stack.

3. Go to the Nth directory from the top without changing the relative positions of the entries in the stack:
$ pushd +N
“rolls up” the stack to bring the directory with index N on top so that now it has index 0 (the indices of other directories in the stack change accordingly so as to keep the relative positions fixed).

4. Effect of cd: substitute the top directory with another_directory:
$ cd another_directory
will replace the top direcotry (index=0) with another_direcotory, as well as you’ll be taken to another_directory.

5. Remove an entry from the directory stack:
$ popd +N
will remove directory with index N counting from top (first is always 0) from the stack. If you remove the top directory (i.e. the working directory, i.e. the one with index 0) you’ll be automatically taken to the next directory in the stack,  whose index then will become 0.

Tilde Expansion [link]

$ echo ~N   # same as: echo `dirs +N`
$ echo ~+N  # same as: echo `dirs +N`
$ echo ~-N  # same as: echo `dirs -N`

Example

$ cd ~N
will replace the top directory with the Nth directory (without any other change in the stack). The same effect may be invoked by
$ pushd -n +N

[bash] Parameter expansions

Tags

, ,

First set a parameter, param1:
$ param1=hello

Now let’s see the result of parameter expansions

$ echo ${param1}  # hello     i.e., same as $param1)
$ echo ${param1}a #
helloa i.e., the braces separate the name
$ echo ${param2}  # (nothing) i.e., nothing there


$ echo ${param2:-file*}    #           lists all files int the working directory starting with file.
$ echo ${param2:-$param1} # hello        uses $param1's value...
$ echo $param2            #(nothing)      ... but didn't change $param2
$ echo ${param3:=$param1} # hello         assigns param1's value to param3
$ echo $param3            #hello 


$ echo ${param1:2}    # llo  i.e., substring from 2
$ echo ${param1:2:2}  # ll   i.e., substring from 2, len 2
$ echo ${param1#he}   # llo  i.e., strip shortest match from start
$ echo ${param1#hel*} # lo   i.e., strip shortest match from start
$ echo ${param1#he*l} # lo   i.e., strip shortest match from start
$ echo ${param1##he*l}# o    i.e., strip longest match from start
$ echo ${param1%l*o}  # hel  i.e., strip shortest match from end
$ echo ${param1%%l*o} # he   i.e., strip longest match from end
$ echo ${param1/l/p}  # heplo i.e., replace as few as possible
$ echo ${param1//l/p} # heppo i.e., replace as many as possible


$ echo ${!param*} # list parameter names starting with param
$ echo ${#param1} # 5 i.e., the length of param

Examples

1. Rename all .GIF files to .gif

$ for file in *.GIF; do mv $file ${file%GIF}gif; done

2. Number the files sequentially

$ cnt=0; for file in *.gif; do mv $file $cnt$file; let cnt=cnt++; done

3. Get rid of the numbers’

$ for file in *.gif; do mv $file ${file##[0-9]}; done

Reference: Directly copied from here with minor changes (as it was in a very-easy-to-understand form in the original).

[bash] Conditional operators in BASH

Tags

, , , , , , ,

-a file
True if file exists.
-b file
True if file exists and is a block special file.
-c file
True if file exists and is a character special file.
-d file
True if file exists and is a directory.
-e file
True if file exists.
-f file
True if file exists and is a regular file.
-g file
True if file exists and its set-group-id bit is set.
-h file
True if file exists and is a symbolic link.
-k file
True if file exists and its “sticky” bit is set.
-p file
True if file exists and is a named pipe (FIFO).
-r file
True if file exists and is readable.
-s file
True if file exists and has a size greater than zero.
-t fd
True if file descriptor fd is open and refers to a terminal.
-u file
True if file exists and its set-user-id bit is set.
-w file
True if file exists and is writable.
-x file
True if file exists and is executable.
-O file
True if file exists and is owned by the effective user id.
-G file
True if file exists and is owned by the effective group id.
-L file
True if file exists and is a symbolic link.
-S file
True if file exists and is a socket.
-N file
True if file exists and has been modified since it was last read.
file1 -nt file2
True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.
file1 -ot file2
True if file1 is older than file2, or if file2 exists and file1 does not.
file1 -ef file2
True if file1 and file2 refer to the same device and inode numbers.
-o optname
True if shell option optname is enabled. The list of options appears in the description of the -o option to the set builtin (see The Set Builtin).
-z string
True if the length of string is zero.
-n string
string
True if the length of string is non-zero.
string1 == string2
True if the strings are equal. ‘=’ may be used in place of ‘==’ for strict posix compliance.
string1 != string2
True if the strings are not equal.
string1 < string2
True if string1 sorts before string2 lexicographically in the current locale.
string1 > string2
True if string1 sorts after string2 lexicographically in the current locale.
arg1 OP arg2
OP is one of ‘-eq’, ‘-ne’, ‘-lt’, ‘-le’, ‘-gt’, or ‘-ge’. These arithmetic binary operators return true if arg1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to arg2, respectively. Arg1 and arg2 may be positive or negative integers.

Reference: Copied directly from here.

[bash] Test if a variable is an integer using BASH script

Tags

, , , , , ,

#!/bin/bash
echo "Enter an integer; I'll test if it's really a one"
read VARIABLE
while [ -z "$VARIABLE" ]; do # Trap empty strings (but there's really no need!)
   echo "Please enter something instead of just hitting ENTER. Thank you!"
    read VARIABLE
done
#
if [ "$VARIABLE" -eq "$VARIABLE" >& /dev/null ]; then # test if integer
    echo "'$VARIABLE' is indeed an integer"
else
     echo "'$VARIABLE' is not an integer"
 fi
 echo "Good bye!"

Save the above in a file, say testint.sh, make it executable and test in the command line. The if statement does an arithmetic comparison which complains a lot if $VARIABLE is not an integer (that’s why there is a redirection!).

[bash] Command line calculator

Tags

, , , ,

Add the following function to the ~/.bashrc or ~/.bash_aliases, source the former and you’ll get a better command line calculator:

? () { echo "$*" | bc -l; }

You can use it the following way:

$ ? 7*3-5.5

and, no doubt that you’ll get 15.5 as the answer.

N.B. If you use parentheses, you must enclose the whole expression by double quotes.

 

UPDATE: An alternative way of using bc
$ bc -l <<< "7*3 - 5.5"

Design a site like this with WordPress.com
Get started