this one works
Actually it doesn't. The read
will parse the line and rebuild it according to shell rules. For example,
echo ' hello world ' |
( read x; echo ">$x<" )
The captured $x
has neither leading nor trailing space:
>hello world<
(Change read x
to IFS= read -r x
and compare the result.) Further, by not double-quoting the variable $x
when you use it, it is subject to further processing. For example,
touch a b c # Create three empty files
x='here is my star: *'
echo "$x" # Outputs: here is my star: *
echo $x # Outputs: here is my star: a b c
In your case the files a
, b
, c
will also be supplemented by the set of files you have in your current directory. (I should point out that touch
only creates empty files as a side effect; if the files already exist it will simply update the last-modified time to now and will most definitely not truncate or recreate them.)
After all that, you won't be able to use the value of $x
outside the loop as you've got the loop in a subshell. (Set x='demo'
before the loop starts and then echo "$x"
after the loop ends. It will have been unaffected by the loop.) You don't need the cat
in this case as there's only one file:
while IFS= read -r x
do
printf '%s\n' "$x"
done <filename
But even after all that, typically there is little need to loop over input like this as many tools process files line by line anyway. c.f.
cat filename
info bash read
and Understanding "IFS= read -r line" and Why is using a shell loop to process text considered bad practice? and Why is printf better than echo? – Stéphane Chazelas Aug 13 '23 at 07:06perl
that have modules to talk to databases. – Stéphane Chazelas Aug 13 '23 at 07:30