For simplicity's sake my preference for this would be the clean and readable solution already posed by Mark Komarinski. However, there are lots of ways to do this in Bash. Another interesting way is to avoid cat
altogether and take advantage of redirection:
find . -name '*.tcl' -exec sh -c 'printf "%s\n" "$(< {})' \;;
In fact, if you want to accomplish the whole task purely with Bash built-ins then you can combine the use of redirection with the glob solution posed by chaos:
shopt_globstar_temp="$(shopt -p globstar)";
shopt -s globstar;
for filename in **/*.bat; do
printf "%s" "$(< "${filename}")";
done;
${shopt_globstar_temp};
These are a bit convoluted, but my point here is to illustrate that Bash can do some powerful things with file descriptors and redirection. There are often many solutions to a given problem.
I don't understand why I have to cat a filename before cat will see it as a file instead of a string though....
The output of cat /dev/fd/stdin
will be the same as the output of find
in your last example, so it will effectively be replaced by <filename1>.tcl <filename2>.tcl ...
and cat
use that file list as its list of arguments.
If you're wondering why you have to cat stdin
in that same example, the reason is that not all programs treat stdin
the same way as they treat arguments. If data is transferred to cat
through stdin
then cat
will simply output that same data instead of interpreting it as a filename to be read.
cat *.tcl
perhaps? Or do you have a directory hierarchy of*.tcl
files to process? – Chris Davies Oct 28 '15 at 17:59