I want to do something repeatedly on a list of files. The files in questions have spaces in their names:
david@david: ls -l
total 32
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha
-rw-rw-r-- 1 david david 0 Mai 8 11:55 haha~
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha (3rd copy)
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha (4th copy)
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha (5th copy)
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha (6th copy)
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha (7th copy)
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha (another copy)
-rw-rw-r-- 1 david david 13 Mai 8 11:55 haha (copy)
Now I want to stat each of these files:
david@david: echo '
for file in $(ls)
do
stat $file
done' | bash
(I use echo and a pipe in order to write multi-line commands.)
When I do that, it works correctly on those files that do not have any spaces in their names. But the others…
stat: cannot stat ‘(another’: No such file or directory
stat: cannot stat ‘copy)’: No such file or directory
Changing $(ls)
to "$(ls)"
or $file
to "$file"
does not work. What can I do?
Edit:
echo '
for files in *
do
stat "$files"
done' | bash
does the trick! As I'm new to bash, I want to keep things as simple as possible – so nothing with trying to escape spaces, or using xargs
or the solution with read -r
, although they solve the problem.
As some have asked: Yes, using this instead of stat *
is weird. But I just wanted to find a general way to apply the same command on a bunch of file names in bash, using a for loop. So stat
could stand for gzip
, gpg
or rm
.
Best Answer
The multiple quote from the
echo '
is complicating the thing.You can just use:
But also
...and if you want to collect the files and then apply the command (why?) you can go with (but be careful with file containing new lines...(1))
...and if you want hidden files too, just use
* .*
as a pattern, but then remember that.
and..
will be in the set.As an aside, you shouldn't parse
ls
output.(1) but if you have file names with newlines, you somewhat deserve it... ;-)