[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[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: