I'd use find
with its -exec
option for this. For example:
TEST='path/with space/to/folder1/'
find "$TEST" -maxdepth 1 -type f -exec cat {} + > test
The -maxdepth 1
option prevents recursion into sub-directories below "$TEST". You can change or remove that as required. -type f
matches only regular files (i.e. excludes directories, named pipes, symbolic links, etc).
If you want it to match specific filename patterns, you can use the -name
or -regex
options (e.g. -name '*.txt'
) or the case-insensitive -iname
/ -iregex
.
find
has a lot more options and is very flexible - but it's also very complex and takes time & effort to learn all that it's capable of. The effort is well worth it, though. Read the man page and practice :-)
One thing worth noting is that find
's predicates are AND-ed together by default. What this means is that if you have -name '*.txt' -name '*.csv'
then it will try to match files ending in .txt and .csv at the same time (which is impossible, so it won't match anything). To OR the predicates, you'd need to do something like:
find "$TEST" -maxdepth 1 -type f \( -name '*.txt' -o -name '*.csv' \) \
-exec cat {} + > test
That will match files ending with either .txt or .csv. The OR-ed predicates are in parentheses to group them, same as in arithmetic. The whole line reads as "find files in directory $TEST to a maximum depth of 1 that are regular files AND (with names ending in either .txt OR .csv) AND execute cat on them. Redirect the output to a file called test"
Also worth noting: The {}
is a placeholder for filename(s) in the -exec
option.
And the +
at the end of the -exec
option tells find
to fit as many filenames as possible on each command line (so it runs cat
as few times as possible). The limit is ARG_MAX, about 2 million bytes worth on a modern Linux system.
You could also use \;
instead of +
- this tells find
to run cat
ONCE per filename (so will be a lot slower, but sometimes having only one filename per run is exactly what you need. Other times, a bulk run with +
is the right thing).
$TEST
is quoted. What's the output oftypeset -p TEST
? – Stéphane Chazelas Mar 24 '23 at 06:12