Saturday, March 28, 2009

Unix commands

Providing default file name arguments to scripts


If a shell script frequently works with files of a special type
(i.e. "*.txt")
a script may use all files of this type in the current directory as default
if no file name is specified.

Example:

# changetextfiles
...
# If no arguments are specified, use all files matching "*.txt"
[ $# -lt 1 ] && set -- *.txt
*************************************************************************************
Comfortable directory list

# Append to .bashrc or call it from there.
# Save some typing at the command line :)

# longlist a directory, by page
# lo [directoryname]
lo () {
if [ -d "$1" ] ; then
ls -al "$1" | less
else
ls -al $(pwd) | less
fi
}

# Same as above but recursive
lro () {
if [ -d "$1" ] ; then
ls -alR "$1" | less
else
ls -alR $(pwd) | less
fi
}
export -f lo lro
*************************************************************************************
Search and replace with extended regular expressions

To perform search-and-replace operations
with extended regular expressions, copy
and paste the following script to
/usr/local/bin/extreg or $HOME/bin/extreg:

#!/bin/sh
if [ $# -gt 1 ]; then
perl -we '$/="'"$2"'";while(<>){'"$1"';print $_}'
else
perl -we 'undef $/;$_=<>;'"$1"';print $_;'
fi

Syntax: extreg regexp [separator]

"regexp" are one ore more extended regular expressions, separated by
semicolon.

"separator" is an optional separator,
see perlvar(1), section
$INPUT_RECORD_SEPARATOR. The data which
has to be processed is divided into
(with the separator ending) blocks, on
which the regular expressions are applied.

If you want to be portable you should
invoke perl directly. "extreg" is primarily meant to be used in your
private scripts or in interactive shell mode.
*************************************************************************************
Indenting lines

To indent all input lines with four blanks use

sed 's/^/    /'

This substitutes the "start-of-line" marker "^" with four spaces.
Since the marker will not disappear, the input

this is
a text

will be rewritten as

____this is
____a text

(The "underscore" character "_" in this example will be a non-visible
space character)
************************************************************************************
How to execute a script for each logout

Sometimes it's useful to execute a command after each
logout, i.e. to cleanup temporary directories, or to log
working hours.

This is the way to make the shell execute the script
$HOME/.atexit after each logout:

1. Insert this line at the beginning of the file
$HOME/.profile:

trap ". $HOME/.atexit" 0

2. Create a file named "$HOME/.atexit", that may contain
arbitrary shell commands, i.e.

$ cat > $HOME/.atexit
echo "Good bye $LOGNAME, the time is `date`"
^D

That's it! After the next login, the shell will execute
the contents of the file "$HOME/.atexit".

NOTE: this will not work for C-Shell dialects, i.e. TCSH
*********************************************************************************
Case-insensitive pattern matching

Some commands do not have a way to match text without considering
the character case, i.e. "awk":

awk '/abc/ { print $1 }'

will find lines containing "abc" but not "ABC" or "aBc". (Of course
in this case you could use "grep -i", but there are situations you
cannot use "grep").

With a little typing you can make this pattern case-insensitive:

awk '/[aA][bB][cC]/ { print $1 }'

This matches all combinations of "abc" with any character case.
You can always rewrite a constant expression like /pattern/
like this: /[pP][aA][tT][tT][eE][rR][nN]/. Just replace
each character "c" with the expression "[cC]" meaning:
either a small "c" or a upper-case "C"
*************************************************************************************
Split a file into multiple files depending on a key value

You have, e.g., a log file to collect logs of different sources;
then you
want to separate the log records depending on a key value defined in the
log data records (the key might identify the source); records with equal
keys should go into the same file.
The program can, of course, be used for other applications than log files,
too.

A nice task for a one-liner... !!

# splitlog.sh - split logfile into multiple logfiles
#
# Depending on some key value in the first column of the logfile defined
# in the argument, it will be split into a set of logfiles, one for each
# key.  If no argument is specified, stdin is used.
#
# Usage: splitlog.sh [ logfile ]
#
# Janis Papanagnou, 2002-11-22

awk -v logfile=${1:-"stdin"} '{ print > logfile"-"$1 }' "$1"

: '--- An example to illustrate...
A file "logfile" with keys A, B, C, and containing the lines, e.g.:
A 489257 8957 38tgzg75ßhg g5hg 5gh27hg 75gh 5hg    0
C 8 c83h5g 85gh 5hg5hg h 8h8gh t2h gtj2            1
B 459 wef2 eruhg uiregn euignutibngtnb ioj         2
B 489257 8957 38tgzg75ßhg g5hg 5gh27hg 75gh 5hg    3
A 459 wef2 eruhg uiregn euignutibngtnb ioj         4

will be split into three files "logfile-A" (only lines with key A):
A 489257 8957 38tgzg75ßhg g5hg 5gh27hg 75gh 5hg    0
A 459 wef2 eruhg uiregn euignutibngtnb ioj         4
"logfile-B" (only lines with key B):
B 459 wef2 eruhg uiregn euignutibngtnb ioj         2
B 489257 8957 38tgzg75ßhg g5hg 5gh27hg 75gh 5hg    3
and "logfile-C" (only lines with key C):
C 8 c83h5g 85gh 5hg5hg h 8h8gh t2h gtj2            1
*************************************************************************************
Copy directory and subdirectories

#!/bin/ksh
#
tarpipe ()
{
# create dest if not already
[ ! -d "$2" ] && mkdir "$2"
# copy it over
tar cCf "$1" - . | tar xCf "$2" -
}

tarpipe "$1" "$2"

or

The following command can be used to copy directories including
subdirectories from one place to another:

src=$HOME
dst=/tmp     # example, must be absolute path

# Create destination directory if it does not exist already
[ -d "$dst" ] || mkdir -p "$dst" || exit 1

cd "$src" &&
find * -print | cpio -pdm "$dst"

This reads and writes the data only once, and therefore usually is more
efficient than using "tar".

*************************************************************************************













Print this post

No comments: