Afficher un message
Vieux 26/07/2007, 00h57   #3
Mister.Fred.Ma@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Bash: Strange quoting in pipelined commands

On Jul 25, 6:14 pm, Michael Tosch <eed...@NO.eed.SPAM.ericsson.PLS.se>
wrote:
> Mister.Fred...@gmail.com wrote:
> > I have the following files/subdirectories listed in List.txt.

>
> > $cat List.txt

>
> > FixDiff.out
> > Temp.txt
> > diff.out
> > dog &cat

>
> > There are no leading or trailing spaces on each line. I want to
> > submit this to "find" after quoting each line. This command seems to
> > do the quoting:

>
> > cat List.txt | sed -e 's/.*/"&"/'

>
> > It generates:

>
> > "FixDiff.out"
> > "Temp.txt"
> > "diff.out"
> > "dog &cat"

>
> > Here is how I fed it to the "find" command. The head command simply
> > ensures that I don't pollute the display with "find" output, and that
> > no time is wasted on the find command, thus enabling me to quickly see
> > the expanded command from "set -x".

>
> > set -x
> > find ` cat List.txt | sed -e 's/.*/"&"/' ` -type f 2>&1 | head -n 0
> > find ` cat List.txt | sed -e 's/.*/&/' ` -type f 2>&1 | head -n 0
> > find ` cat List.txt | sed -e "s/.*/'&'/" ` -type f 2>&1 | head -n 0

>
> > Here is the output:

>
> > $ find ` cat List.txt | sed -e 's/.*/"&"/' ` -type f 2>&1 | head -n 0

>
> > find '"' 'FixDiff.out"' '"' 'Temp.txt"' '"' 'diff.out"' '"' dog
> > '&cat"' -type f

>
> > $ find ` cat List.txt | sed -e 's/.*/&/' ` -type f 2>&1 | head -n 0

>
> > find FixDiff.out Temp.txt diff.out dog '&cat' -type f

>
> > $ find ` cat List.txt | sed -e "s/.*/'&'/" ` -type f 2>&1 | head -n 0

>
> > find ''\''' 'FixDiff.out'\''' ''\''' 'Temp.txt'\''' ''\'''
> > 'diff.out'\''' ''\''' dog '&cat'\''' -type f

>
> > The 1st "find" is what I expected to work, but it generates extra
> > single-quotes. The 2nd "find" is a debugging step to find out exactly
> > what happens when the 4-line output of "cat | sed" is put onto a
> > single physical line for "find". Apparently, spaces are not
> > protected, though ampersands are. Leading quotes are protected, but
> > are considered separated out as distinct arguments.

>
> > The above is just a illustration of this behaviour. The actual usage
> > involves grepping a file instead of cat'ing it. The result is even
> > stranger -- using the 1st "find" above, only the 1st 2 filenames
> > contain quotes (wrong though they may be), while the remaining large
> > number of filenames have not quoting at all.

>
> > Is there a way to generate the required quoting? I realize I can
> > prepend backslashes to all nonstandard characters, but simply quoting
> > the whole thing seemed alot simpler than identifying all nonstandard
> > characters -- if it can be made to work.

>
> > Why do the above 3 "find" commands generate such strange quoting?

>
> > Thanks!

>
> The `` generates a list of IFS-separated tokens.
> It is safer to read the file line by line,
> and each time run a find command:
>
> while read -r line
> do
> find "$line" ...
> done < List.txt


Thanks, Michael. It works like a charm. I also learned that you can
pipe into a loop using "<" at the end, or using "|" at the start.

I looked up bash's "read", but I'm confused by the delimiting. It
says the IFS variable (which I assume is the default, since I didn't
change it) delimits the words in the line. The -r switch simply says
that backslashing isn't used -- not sure where that fits in, since I
don't have such a character in List.txt. It does not say that IFS is
ignored -- yet this must be what is happening, since the entire
contents of the physical line is stuffed into $line (else the find
command would report and error). So why is -r needed, and why is IFS
*apparently* not used here?

Thanks!

  Réponse avec citation
 
Page generated in 0,06911 seconds with 9 queries