I have hundreds of files in one directory, is there a simple command or pipes of command I can use to append them together? I don't want to use any loops.
4 Answers
cat * >/path/to/somewhere
don't do
cat * > toall.txt
because "toall.txt" is created before cat is started and you will get strange result, "cat"ing toall.txt into toall.txt.
if want cat in the current directory, you should use
cat [some_globbing] > file #or
cat * > .dotted_file
.dotted_file is not expanded by *
globbing.
or for example
(ls *.txt | xargs cat ) > /some/file
If there aren't too many files:
cat * > /some/new/file
Otherwise:
find . -exec cat {} + > /some/new/file
find . -exec cat {} \; > /some/new/file
-
It'd probably be worth noting that the first one is GNU find-specific, and works similarly to "find|xargs". :) Commented Jun 21, 2011 at 19:59
-
1
-
Is the BSD you're using running a GNU find? :) "find --version" If not, then I learned something today. Commented Jun 21, 2011 at 20:11
-
-
I'm not shocked that OSX's command line is similar to that of FreeBSD. ;) But the man page looks suffieciently different. I'm glad to see some portability; I know it does not work on my HP-UX or AIX boxes using their POSIX-compliant find. :) Commented Jun 21, 2011 at 20:21
Similar to Ignatio's suggestion:
rm /the/output && find . -print0 | xargs -0 cat >> /the/output
Without using xargs, you're apt to blow your maximum command line length. Without using -print0, you'll potentially have problems with files that have weird chars (like spaces) in the names. But that's also GNU-specific.
This will append all files to outfile:
for file in !(outfile); do
cat "$file" >> outfile
done
You need to delete outfile first if it exists. This will however not catch the dot-files. If you want to catch those as well you can use the two patterns
.??* !(outfile)
to create your file list. It requires a dot-file to have at least length 3, hence excludes . and ..!
cat
processes.