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!
|