20

I want to cat all the files in a directory, but include some spacer between each one.

Matt
  • 269
  • 1
  • 3
  • 10

5 Answers5

21

use awk

awk 'FNR==1{print ""}{print}' file* > out.txt
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • Nasty recursion. But this works: awk 'FNR==1{print ""}{print}' *.txt > /tmp/out.txt – Matt Oct 31 '09 at 01:46
  • what do you mean nasty recursion.? – ghostdog74 Oct 31 '09 at 01:55
  • 1
    If I run that line alone the command never quits, and keeps appending the files to the out.txt (which is in the same folder of the files I'm cat-ing. Out.txt gets very large, very fast. (Again, OSX 10.5.8 YRMV). – Matt Oct 31 '09 at 01:58
  • file* in my example means processing files with file names starting with file. therefore if you have names like file1, file2, file3 then it will process. The only difference now is you change to *.txt. I could only guess that you have MANY files with names starting with file?? If not, I don't see why it will into recursion and never quits, as it works for me. Anyway, since there's a work around for you, then should be fine. – ghostdog74 Oct 31 '09 at 02:04
  • EDIT-I'm a noob, and was doing `* > out.txt`, duh. Your answer is great (but not "cat", not sure I should select it as the "real" answer?). Thanks much. – Matt Oct 31 '09 at 02:28
  • 2
    `awk 'FNR==1{}{print}' file* > out.txt` worked better for me. Thanks. – rahul286 Jun 12 '14 at 11:38
  • @rahul286 How exactly does that work better for you? In my testing it doesn't work at all. – Caleb Dec 10 '16 at 14:20
13

Try

find . -type f -exec cat {} \; -exec echo "-- spacer --" \;

Obviously, the 'spacer' can be more than the simple example used here.

pavium
  • 14,808
  • 4
  • 33
  • 50
2

You might want to see pr(1), which may do what you want out-of-the-box.

To roll your own, expand this posix shell script fragment:

ls -1  | while read f; do cat "$f"; echo This is a spacer line; done > /tmp/outputfile

This might more readably be written as:

ls -1 | while read f; do
    cat "$f"
    echo This is a spacer line
done > /tmp/outputfile

You don't really need the -1 for ls.

DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
  • Thanks! Just remember to redirect the output to another directory (as in the awk solution). – Matt Oct 31 '09 at 01:55
  • You don't need the `ls` at all. Just `for f in *; do cat ...` (http://porkmail.org/era/unix/award.html#ls) – Jacktose Mar 19 '19 at 20:18
-1

I think the simplest way is using the paste command:

paste $(ls *) > file.out
Caleb
  • 5,084
  • 1
  • 46
  • 65
  • Um, no, this just doesn't work. Paste does something similar but different to what the question asked. It interlaces the files. – Caleb Dec 10 '16 at 14:07
-2

echo "" > blank.txt
cat f1.txt blank.txt f2.txt blank.txt f3.txt

To handle all of the files in a Directory (assuming ksh like Shell)

for file in * ; do
   cat $file >> result.txt
   echo "" >> result.txt
done

Rob Moore
  • 1
  • 1
  • That doesn't take care of all files in the directory unless you manually list them as parameters. – Ian Gregory Oct 31 '09 at 01:29
  • be careful if you cat like that with a for loop expanding everything. $file could be a directory and you will be catting a directory. – ghostdog74 Oct 31 '09 at 01:59