Reputation: 26
Any one know why this works?
cat `echo "FilenameWithoutSpaces.txt"` # shows file content
stdout:
SHOW FILE CONTENT
And this not?
cat `echo "Filename\ With\ Spaces.txt"` # trying to show "Filename With Spaces.txt" content
stdout:
cat: 'Filename': No such file or directory
cat: 'With': No such file or directory
cat: Spaces.txt: No such file or director
What would be the correct way to pass an output (with spaces) as a input of another command?
The example above is a simplified case of what i need. What I have to to is:
To use list of files (that may contain spaces) returned by a command as argument for another command.
Upvotes: 1
Views: 1611
Reputation: 212288
For this particular case:
cat "$(echo "Filename\ With\ Spaces.txt")"
Since the case is a bit contrived, I can't really say what the correct thing is for your actual situation. What is meant by a "list of files"? Is that a list of files that are separated by newlines? How will you handle files that contain a newline in the name? Is it a list of null separated files, or is the list comma separated? In general, my opinion would be that the correct solution is to ban the use of whitespace in filenames. If that's not an option, the general principle would be to always put quotes around any string that may contain elements of IFS.
However. (Note this "however" should be read as "the following is a terrible hack that should never be done because the correct approach is to ban the use of whitespace in filenames"). Assuming that by a "list of files" you mean that each name is distinguished from the next by the presence of a newline in the string, you might try something like:
printf '1st name\n2nd name\n' | { a=(); while read arg; do a+=("$arg"); done;
cmd "${a[@]}"
}
The above will invoke cmd
with each line as a single argument. It would be much more reasonable to require that the list of inputs be zero separated, which would allow you to use xargs
with something like:
printf '1st name\0002nd name\000' | xargs -0 cmd
Until you properly define what you mean by "list of files", no robust solution is possible.
Upvotes: 1
Reputation: 3251
This is due to the way strings are handled and passed are argument in bash. When you run echo "Filename\ With\ Spaces.txt"
the output is Filename With Spaces.txt
which is exaclty what you are expecting. So the full command is essentially the same as cat Filename With Spaces.txt
and cat is trying to find 3 files with the names Filename, With, and Spaces.txt.
When bash looks for those is it not likely to find them and spits out those error messages you are seeing. When there are no spaces, the filename is read as a single parameter and so you do not encounter the same issue.
To force the command to work with and without spaces you need to add qutoations around the command substituion:
cat "`echo "Filename\ With\ Spaces.txt"`"
This command will expand the out put of the echo
and keep it as a single argument.
Upvotes: 0