|
|
|
|
||||||
| comp.unix.shell Using and programming the Unix shell. |
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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! |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Mister.Fred.Ma@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 -- Michael Tosch @ hp : com |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
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! |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
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! |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Mister.Fred.Ma@gmail.com wrote:
> 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? > In case List.txt has line\ 1 a normal read would compose that to "line1", therefore the -r IFS is used to split the line: while read -r word1 word2 rest But we read the entire line. -- Michael Tosch @ hp : com |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Jul 25, 7:24 pm, Michael Tosch <eed...@NO.eed.SPAM.ericsson.PLS.se>
wrote: > Mister.Fred...@gmail.com wrote: > > 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? > > In case List.txt has > > line\ > 1 > > a normal read would compose that to "line1", therefore the -r > > IFS is used to split the line: > > while read -r word1 word2 rest > > But we read the entire line. Thanks, Michael. Fred |
|
![]() |
| Outils de la discussion | |
|
|