: ########################################################################## # Title : mreplace - match and replace multiple expressions # Author : Heiner Steven # Date : 2004-10-11 # Category : Text Utilities # Requires : nawk # SCCS-Id. : @(#) mreplace 1.1 04/10/11 ########################################################################## # Description # ########################################################################## PN=`basename "$0"` # Program name VER='1.1' usage () { echo >&2 "$PN - match and replace multiple expressions, $VER usage: $PN [-h] -f mapfile file [...] -f: mapfile (\"-\" for standard input) -h: print this usage summary The mapfile contains lines in the format regexpstring where each occurance of the regular expression regexp is replaced with the corresponding string. The sequence in which the regular expressions appear in the file may not be the same order in which the substitutions are made." exit 1 } msg () { echo >&2 "$PN:" "$@"; } fatal () { msg "$@"; exit 1; } ########################################################################## # searchprog - search program using search PATH # usage: searchprog program ########################################################################## searchprog () { _search=$1; shift for _dir in `echo "$PATH" | sed "s/^:/.:/;s/:\$/:./;s/::/:.:/g;s/:/ /g"` do [ -x "$_dir/$_search" ] || continue echo "$_dir/$_search" return 0 done return 1 } ########################################################################## # Search for a newer AWK implementation, prefer the fastest one : ${NAWK:=`searchprog mawk || searchprog gawk || searchprog nawk || echo awk`} while getopts :hf: opt do case "$opt" in # your flags here f) MapFile=$OPTARG;; h) usage;; ?) usage;; esac done shift `expr ${OPTIND-1} - 1` [ -n "$MapFile" ] || usage [ X"$MapFile" = X"-" ] && [ -s "$MapFile" ] || fatal "cannot read mapfile: $MapFile" $NAWK ' BEGIN { mapfile = "'"$MapFile"'" while (getline < mapfile) { if ( NF < 2 ) continue o = $1 n = substr($0, length(o)+1) sub(/^[ ]*/, "", n) rep[o ""] = n } #for (r in rep) print "<" r "> <" rep[r] ">" for (r in rep) { for (s in rep) { if (match(rep[s], r)) { print "WARNING: circular match:", r, "could be replaced with", rep[s] | "cat >&2" } } } } { out = $0 for (r in rep) { while (match (out, r)) { print "<", out if (RSTART <= 1) { s = rep[r] substr(out, RSTART+RLENGTH) } else { s = substr(out, 1, RSTART-1) rep[r] \ substr(out, RSTART+RLENGTH) } out = s } } print out } ' "$@"