Thank you for that script. I experimented a bit with it and have a number of 
corrections and suggestions:

- alias does not work because my_sed is not declared at this stage. I removed 
the whole alias line because I want to selectively enable my_sed
- oargs must be an array in order to make quoting work:

   local oargs=( "${@}" )

- In the ewarn line ${oargs} should be changed to ${nargs[@]} (!?)
- is it correct to treat -e and -f alike ? I am not sure about that, because 
the latter expects a file
- If no "-e" is given, the first non-option argument is treated as the sed-
script-expression, therefore I added hade=yes in the if-branch

The new function now reads:

my_sed() {
        local oargs=( "$@" )
        local arg
        local nargs=()
        local hadi=
        local hade=

        while [[ -n $1 ]] ; do
                case "$1" in
                -i|--in-place)
                        # ignore this flag
                        hadi=yes
                        ;;
                -e|--expression)
                        shift
                        nargs+=( "-e" "$1" )
                        hade=yes
                        ;;
                -f|--file)
                        shift
                        nargs+=( "-f" "$1" )
                        hade=yes
                        ;;
                -*)
                        nargs+=( "$1" )
                        ;;
                *)
                        if [[ -z ${hade} ]] ; then
                                nargs+=( "-e" "$1" )
                                hade=yes
                        elif [[ -z ${hadi} ]] ; then
                                # there is no inline replacing, not much we can 
do
                                break
                        else
                                sed "${nargs[@]}" "$1" | diff -q "$1" - > 
/dev/null && \
                                        ewarn "sed ${nargs[@]} has no effect on 
$1" 
                        fi
                        ;;
                esac
                shift
        done

        sed "${oargs[@]}"
}

As you can see, I added support for long-options. However, testing the 
individual sed commands remains to be done. This could be especially difficult 
if input is taken from stdin (e.g. in cat foo | sed "s:a:b:g").

I tested my_sed within our sage ebuild[1]. This ebuild contains 39 sed 
commands and I was able to spot one useless sed.



[1] https://github.com/cschwan/sage-on-gentoo/blob/master/sci-
mathematics/sage/sage-4.7.ebuild


On Sunday 22 May 2011 12:50:43 Fabian Groffen wrote:
> On 21-05-2011 19:34:34 +0200, Jeroen Roovers wrote:
> > On Fri, 20 May 2011 17:56:00 +0200
> > 
> > Fabian Groffen <grob...@gentoo.org> wrote:
> > >   sed -e "<pattern>" "${file}" | diff "${file}" -
> > > 
> > > followed by the actual sed -i -e ...
> > > 
> > > This way I didn't need to write an intermediate file.
> > 
> > The problem there is that sed might be called just once on any one file,
> > but in the tree it is often invoked with multiple scripts, so this
> > simple implementation lacks a way to evaluate which sed scripts are
> > useful.
> > 
> > Also, how do I ensure the sed replacement works only on invocations
> > inside the ebuild, and not, say, in portage's internals?
> 
> (not tested, but as proof of concept)
> 
> alias sed my_sed
> my_sed() {
>       local oargs="${@}"
>       local arg
>       local nargs=()
>       local hadi=
>       local hade=
>       while [[ -n $1 ]] ; do
>               case "$1" in
>                       -i)
>                               # ignore this flag
>                               hadi=yes
>                               ;;
>                       -e|-f)
>                               shift
>                               nargs+=( "-e$1" )
>                               hade=yes
>                               ;;
>                       -*)
>                               nargs+=( "$1" )
>                               hade=yes
>                               ;;
>                       *)
>                               if [[ -z ${hade} ]] ; then
>                                       nargs+=( "$1" )
>                               elif [[ -z ${hadi} ]] ; then
>                                       # there is no inline replacing, not 
> much we can do
>                                       break
>                               else
>                                       sed "${nargs[@]}" "$1" | diff -q "$1" - 
> > /dev/null \
>                                               && ewarn "sed ${oargs} has no 
> effect on $1"
>                               fi
>                               ;;
>               esac
>               shift
>       done
> 
>       \sed "${oargs}"
> }

Reply via email to