How to cat multiple files from a list of files in Bash?
xargs cat < files
The advantage of xargs over $(cat)
is that cat
expands to a huge list of arguments which could fail if you have a lot of files in the list due to Linux' maximum command line length.
Example without caring about #
:
printf 'a\nb\nc\n' > files
printf '12\n3\n' > a
printf '4\n56\n' > b
printf '8\n9\n' > c
xargs cat < files
Output:
12
3
4
56
8
9
More specific example ignoring #
as requested by OP:
printf 'a\nb\n#c\n' > files
printf '12\n3\n' > a
printf '4\n56\n' > b
printf '8\n9\n' > c
grep -v '^#' files | xargs cat
Output:
12
3
4
56
Related: How to pipe list of files returned by find command to cat to view all the files
Or in a simple command
cat $(grep -v '^#' files) > output
#!/bin/bash
files=()
while read; do
case "$REPLY" in
\#*|'') continue;;
*) files+=( "$REPLY" );;
esac
done < input
cat "${files[@]}"
What's better about this approach is that:
- The only external command,
cat
, only gets executed once. - It's pretty careful to maintain significant whitespace for any given line/filename.
{
while read file
do
#process comments here with continue
cat "$file"
done
} < tmp > newfile