2

I would like to merge all the files under a folder and its subfolders into a file total.txt, so I try

find . -type f -exec cat {} +; > total.txt

and the output can't be redirected

pipe can't work either:

find . -type f -exec cat {} + | cat > total.txt

It maybe caused by -exec which takes all the arguments after it as the command?

Is it right? And how to fix it? Or is there a better way to achieve this.

Any help will be appreciated :)

3
  • I find that your second method works reasonably well. What problem do you see with it? Commented May 9, 2015 at 3:25
  • @nobar it run for a long time and seems never ends Commented May 15, 2015 at 3:00
  • 2
    I bet that was because it was copying total.txt into itself. This didn't happen when I tested with small files, but it did happen once I had enough content in the folder -- it would probably keep reading and writing the growing total.txt until it filled up the disk. This is why William suggested copying to .. and I suggested using ! -path ./total.txt. Commented May 15, 2015 at 3:41

2 Answers 2

2

There are a few issues. The semi colon is terminating the command, so you are running two commands, with the second being an empty redirect. Secondly, you need to prevent find from finding the file it is writing to, and an easy way to do that is to move it up a directory:

 find . -type f -exec cat {} + > ../total.txt
Sign up to request clarification or add additional context in comments.

Comments

0

Here's a simple way...

## WARNING: this only works for simple cases...
cat $(find ! -path ./total.txt -type f ) >total.txt

Here's another way, which is more robust to various special cases, such as spaces in file names or a very large number of files...

find ! -path ./total.txt -type f -print0 |xargs -0 cat >total.txt

7 Comments

By the way, ! -path ./total.txt is only necessary based on the assumption that you want to write the file into the same directory that you are scanning.
thank you, it works! could you please give a short explanation of $ 's usage
@simon_xia: It is command substitution -- the output of the command replaces the command on the command-line. For example cat $(ls *.txt) might become cat file1.txt file2.txt.
Why show the buggy form at all when you have the correct one?
@CharlesDuffy: It's useful to point out the limitations of the simpler approach.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.