So one can easily join files in bash with cat:

cat *.txt > all.txt

But what if one wants to insert something between the input files, like for example a linefeed?

link|improve this question
feedback

2 Answers

up vote 2 down vote accepted

Requires GNU sed:

sed -s '$G' *.txt > all.txt

append a line of 8 dashes and a newline after each file

sed -s '$a--------' *.txt

You can use your sed '$d' with that

Compare to these:

Insert a line of dashes before each file:

sed -s '1i--------' *.txt

Do the same, but without a newline after the dashes:

sed -s '1s/^/--------/' *.txt

Put a line of dashes on the end of the last line of each file:

sed -s '$s/$/--------/' *.txt

Surround each file with curly braces:

sed -s -e '1i{' -e '$a}' *.txt
link|improve this answer
Elegant solution for inserting linefeed, I made a small modification to only have the linfeeds between the original files not at the end: sed -s '$G' *.txt | sed '$d' > all.txt But can this method also be used to insert other data, to be more in line with the general question? – Roger Ertesvag Feb 3 '10 at 7:16
@Roger: sed -s '$a--------' *.txt would append a line of 8 dashes and a newline after each file. You can use your sed '$d' with that. Compare to these: sed -s '1i--------' *.txt, sed -s '1s/^/--------/' *.txt, sed -s '$s/$/--------/' *.txt and sed -s -e '1i{' -e '$a}' *.txt – Dennis Williamson Feb 3 '10 at 11:09
could you add these options to the answer? – Roger Ertesvag Feb 4 '10 at 10:32
feedback

As a one-liner with subshells:

( for i in *.txt ; do cat $i ; echo 'separator here' ; done ) >all.txt

Here's what the subshell executes split into script-style lines:

for i in *.txt
do
cat $i
echo 'separator goes here' 
done

In this example the separator acts like a footer; add a header by adding another echo before the cat.

link|improve this answer
1  
There is no need for the subshell, and you should use double quotes around the variable expansion to protect any whitespace in the filenames. for i in *.txt; do cat "$i"; echo 'stuff'; done > all.txt – Chris Johnsen Feb 2 '10 at 1:06
Can this be modified to not insert the separator at the end of the result file, only between the original files? – Roger Ertesvag Feb 3 '10 at 7:19
@Roger: files=(*.txt); indices=(${!files[@]}); for i in ${indices[@]}; do cat "${files[i]}"; if [[ $i != ${indices[@]: -1} ]]; then echo "separator"; fi; done > all.txt – Dennis Williamson Feb 3 '10 at 11:19
1  
catWithSep() { sep="$1"; shift; first=''; for f; do test -n "$first" && echo "$sep"; cat "$f"; first=no; done; }; catWithSep separator *.txt – Chris Johnsen Feb 3 '10 at 11:56
@Chris: nice one! – Dennis Williamson Feb 3 '10 at 19:43
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.