Cameron Simpson wrote:

> On Fri, Jan 05, 2001 at 07:03:12PM -0800, Brad Doster <[EMAIL PROTECTED]> wrote:
> | Thanks, Cameron.  It's a cool idea, but I can't get the leading and trailing
> | spaces to stick within a variable.  The following script and it's output
> | will show you what I mean:
> |
> | list="one two three four"
> | list=`echo $list | sed "s/^/ /"`
> | echo $list
> | list=`echo $list | sed "s/$/ /"`
> | echo $list
> [...]
> | Is there a way to get leading and trailing spaces (and multiple spaces
> | between words) to stick in variables, or this a "feature" of bash?
>
> Actually, the spaces would stick but you're throwing them away!
>
> Come, let us read from "man sh" (which is bash on most/all Linux systems):
>
>      Command Substitution
>        Command  substitution  allows  the  output of a command to
>        replace the command name.  There are two forms:
>
>               $(command)
>        or
>               `command`
>
>        Bash performs  the  expansion  by  executing  command  and
>        replacing  the command substitution with the standard out
>        put of the command, with any trailing newlines deleted.
>
> (Other Bourne shells act the same, though not all support the $(...) variation.)
> So, only trailing newlines are stripped by the ``.
> However, your echo statement is doing space interpretation because the $list
> is unquoted. Observe the different behaviours here:
>
> bash$ foo=' a b c '
> bash$ echo $foo
> a b c
> bash$ echo "[$foo]"
> [ a b c ]
>
> (Those [] are just markers, not syntactically special - they're there to show
> the boundaries of what's in $foo.)
>
> $foo is "a b c ". So the first echo becomes the command
>
>         echo  a b c
>
> Note the two spaces after "echo" and one at the end of the line. Then the shell
> breaks that into words, making the command words:
>
>         "echo" "a" "b" "c"
>
> (Those quotes are just to show the words - they're not `shell' quotes).
> Which prints
>
>         a b c
>
> without leading or trailing spaces. The second echo statement has quoted the
> argument, so the [$foo] is not broken up on whitespace. The command words
> are
>
>         "echo" "[ a b c ]"
>
> this time i.e. 2 strings, not four.
>
> Watch this:
>
>         bash$ echo $foo ; echo "$foo"
>         a b c
>          a b c
>
> Perhaps that makes it clearer. So, you want to say:
>
>         list=`echo "$list" | sed "s/ four / /"`
>
> and not:
>
>         list=`echo $list | sed "s/ four / /"`
>
> Also, you want to use '' instead of "" in the sed argument. Otherwise your $
> in "s/ $//" can be misinterpreted. It is best to use '' unless you really
> need parameter substitution to occur. Safer.
>
> Also, you can do several things with one sed, which also faster:
>
>         list=`echo "$list" | sed 's/^/ /
>                                   s/$/ /
>                                   s/ one / /
>                                   s/ four //
>                                   s/^ //
>                                   s/ $//'`
>
> Concise and readable. It also neatly sidesteps a lot of the quoting
> issues because you do all the adding and then removing of spaces inside
> sed and never have to pass the intermediate versions of the line back
> out to $list.
>
> For complex things I sometimes put the sed script in a file (sed is a
> programming language with loops, blocks, tests and conditional
> branches), thus:
>
>         bash$ ed sedf
>         sedf: No such file or directory
>         a
>         s/^/ /
>         s/$/ /
>         s/ one / /
>         s/ four //
>         s/^ //
>         s/ $//
>         .
>         w
>         156
>         q
>
> and then go like this:
>
>         list=`echo "$list" | sed -f sedf`
>
> Does this make stuff clearer?
> --
> Cameron Simpson, DoD#743        [EMAIL PROTECTED]    http://www.zip.com.au/~cs/
>

Outstanding explaination, Cameron.  Thanks

Bret




_______________________________________________
Redhat-list mailing list
[EMAIL PROTECTED]
https://listman.redhat.com/mailman/listinfo/redhat-list

Reply via email to