Escaping quote marks

James Michael Fultz croooow at gmail.com
Fri Nov 20 23:01:43 UTC 2009


* Ray Parrish <crp at cmc.net> [2009-11-20 04:24 -0800]:
> I have the following code which I would like to improve.
> 
>     URLs=""
>      while read ThisLine; do
>            case "$ThisLine" in
>                 *\<loc\>*) # if line starts with <loc> concatenate it 
> into string variable URLs.
>                          URLs="$URLs $ThisLine";;
>            esac
>      done < "$MapName"
>      # Prompt user with drop down list of urls to select one to remove 
> from site map.
>      SelectedLine=`Xdialog --stdout --title "Add URL to Site Map - 
> Remove URL" --combobox "Select web page to remove from site map" 10 70 
> $URLs`
> 
> The problem is that if any of the iines starting with <loc> contain 
> spaces in their file names, the combobox presents them broken up at the 
> spaces on separate lines in it's drop down list.
> 
> I have tried to escape quote marks wrapped around each $ThisLine 
> concatenated to the URLs string variable as below to make them 
> individual parameters, but when I do this the quote marks get written to 
> the drop down list, and the entries are still broken at each space.
> 
>                          URLs="$URLs \"$ThisLine\"";;
> 
> Is there any way to get the code to work correctly so it does not break 
> the urls on space characters?

read doesn't just read in a line by default -- it splits lines into
fields based on the value of $IFS which defaults to space, tab, and
newline.  Setting $IFS to a null value will cause read to read in
a complete line.  The '-r' option is also recommended to preserve
embedded backslash characters.

        while IFS= read -r ThisLine; do

In a later message, you make mention of Bash.  If you are in fact using
Bash for your script, an array for $URLs would be better for your
purposes.

        URLs=()
        while IFS= read -r ThisLine; do
                case $ThisLine in
                *'<loc>'*)
                        URLs+=( $ThisLine )
                        ;;
                esac
        done < "$MapName"
        SelectedLine=$(Xdialog --stdout \
                --title "Add URL to Site Map - Remove URL" \
                --combobox "Select web page to remove from site map" \
                10 70 "${URLs[@]}")

Also, you could use Bash parameter expansion to replace spaces with %20.

        case $ThisLine in
        *'<loc>'*)
                url=${ThisLine// /%20}
                URLs+=( $url )
                ;;
        esac

Alternatively, the following would work in any POSIX shell (/bin/sh).

        url=$(echo "$ThisLine" | sed 's/ /%20/g')




More information about the ubuntu-users mailing list