All pastes #514338 Raw Edit

mreplace

public text v1 · immutable
#514338 ·published 2007-05-27 18:02 UTC
rendered paste body
:
##########################################################################
# Title      :  mreplace - match and replace multiple expressions
# Author     :  Heiner Steven <heiner.steven@odn.de>
# 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
        regexp<whitespace>string

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
    }
' "$@"