bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sed


From: Stephane Chazelas
Subject: Re: sed
Date: Tue, 13 Feb 2007 09:07:36 +0000
User-agent: Mutt/1.5.6i

On Mon, Feb 12, 2007 at 09:19:24AM -0800, Conner, Neil wrote:
> I may have found a bug in sed.  Take a look at the attached files and let me 
> know what you think.
> 
>  
> 
> Environment: ksh on HPUX 11i.  I cannot get sed to output a
> backslash character "\" in the replacement string.  It will
> output other characters meaningful to the shell like "&".

                #
                # READ mangles backslashes in input strings.
                # Without the -r option, backslashes are deleted.
                # With the -r option, the first two occurrences
                # of a backslash and the next character following it
                # are replaced with ^K.
                #
                # Use sed to restore the input string.
                #
                ALERT=`echo $TEMP | sed s//\\v/g`

You've got 4 errors in that single line.

1- "echo" is a command to expand the \b, \n, \r... not the
command to display some text verbatim

\v for it is the vertical tab, ^K.

echo '\v'

outputs a vertical tab followed by a line feed.

You want the POSIX printf '%s\n' or the ksh/zsh specific print
-r --.

2- You left $TEMP unquoted. Leaving a variable unquoted has a
very special meaning to the shell, it means some kind of very
special list. Basically, the shell will split $TEMP and try to
consider each word as a globbing pattern. So:

printf '%s\n' "$TEMP"

3- The "\" character is special to the shell, special to sed,
and special to the backticks, so you should escape it 3 times in
that case.

ALERT=`printf '%s\n' "$TEMP" | sed s//\\\\\\\\v/g`

or use single quotes:

ALERT=`printf '%s\n' "$TEMP" | sed 's//\\\\v/g'`

and use $(...) instead of `...`

ALERT=$(printf '%s\n' "$TEMP" | sed 's//\\v/g')

4- You used an empty pattern (//)

For sed, an empty pattern means to reuse the previously used
pattern. Here there isn't any

And I shall add about coding practices:

5- don't use "while read" loops.
6- use the standard sh syntax instead of trying to rely on any
version and implementation of an unspecified shell like ksh or
bash (and have bash or ksh interpret that syntax if you wish as
those are standard conformant shells).

Your script should read:


NEW_ALERTS=/tmp/zzz

cat < "$NEW_ALERTS" &&
  sed 'x;p;x;p;x;p;x;s/PATTERN/\\v/g'


or:

NEW_ALERTS=/tmp/zzz

cat < "$NEW_ALERTS" &&
  awk '{
    print "\n" $0 "\n"
    gsub(/PATTERN/, "\\v")
    print}'


-- 
Stéphane




reply via email to

[Prev in Thread] Current Thread [Next in Thread]