[g.l.d.user] Re: A quick Q: how do I command something in large amount
The following message is a courtesy copy of an article
that has been posted to comp.unix.shell as well.
>>>>> Arnt Karlsen <arnt@c2i.net> writes:
>>>>> On Fri, 16 Sep 2011 00:17:47 +0700, Ivan wrote:
[Cross-posting to comp.unix.shell for no good reason at all.]
>> Whitespace is not a problem as long as one remembers to double-quote
>> Shell $ubstitutions, like:
>> for i in a b c ; do
> ..or, e.g.: for i in $(ls /path/to/files/*.txt ) ; do
No, it isn't whitespace-tolerant, as the result of the unescaped
$()-substitution is subject to IFS-splitting. The correct form
would be:
for i in /path/to/files/*.txt ; do something ; done
Consider, e. g.:
$ ls -1
a
b c
$ (for x in $(ls *) ; do echo ."$x". ; done)
.a.
.b.
.c.
$
Moreover, ls(1) is an extra here; the command above requests the
Shell to search for all the .txt filenames in /path/to/files/,
then the filenames are passed to ls(1), which is supposed to
pass them back to the shell unaltered. There, ls(1) may
essentially behave the same as, say, $ echo, or $ printf %s\\n.
This is somewhat akin to UUoC, as in:
$ cat < "$file" | grep something
vs. simply:
$ grep something < "$file"
Or it may not. Consider that one of the .txt-filenames refers
to a directory, like:
$ ls -1RF
.:
a
b c
d/
./d:
x y
$ (for x in $(ls *) ; do echo ."$x". ; done)
.a.
.b.
.c.
.d:.
.x.
.y.
$
Note that the above has ‘x’ set to ‘d:’, ‘x’ and ‘y’, neither of
whose belong to the current directory.
(NB: the term “path” is also considered obsolete by GNU when
speaking of “whole names”, as opposed to “search paths”, such
as, e. g., "$PATH" or "$CDPATH". In particular, GNU find(1)
states that -wholename is preferred to -path.)
>> txt2pdf -input "${i}.txt" -out "${i}.pdf"
>> done
> ..disclaimer: I've only used the alleged obsolete back-tick way. ;o)
The backticks are harder to both nest and mix with other Shell
substitutions and escapes. Consider, e. g.:
$ echo \\\"
\"
$
To put the stdout of the command above into a Shell variable, we
may use either the $()-substitution:
$ x=$(echo \\\") ; echo "$y"
\"
$
or the backticks:
$ y=`echo \\\\\\"` ; echo "$y"
\"
$
Now, can you explain why the backslashes above have to be
doubled in the latter case?
--
FSF associate member #7257
Reply to: