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:
Post a Comment