4

I'm trying to join Markdown files with two newlines between each file.

I've tried using the following command:

paste -sd '\n\n' file1.md file2.md

This joins the files with a newline, but not two newlines, as I need.

What command can I use to join an arbitrary number of files with two \n characters between each join?

don_crissti
  • 82,805
Naftuli Kay
  • 39,676

6 Answers6

4

With paste:

:|paste -sd'\n' file1.md - - file2.md
cuonglm
  • 153,898
2

With awk you could process multiple files and print a delimiter before each file (FNR==1) except for the first one (NR>1). So

awk '(NR>1 && FNR==1){printf ("\n\n")};1' file1.md file2.md ... fileN.md

concatenates the files adding the specified delimiter in-between.


If you don't mind a trailing delimiter in the final output, in this particular case (the delimiter is a number of empty lines) you could also do (with gnu sed):

sed -s '${G;G}' file1.md file2.md ... fileN.md
cuonglm
  • 153,898
don_crissti
  • 82,805
2

In addition to cuonglm's answer:

:|paste -sd'\n' $(sed $"s/\s/ - - /g" <<< $(ls -1|paste -sd" " -))

For this to work you need to have all files, that should be concatenated within one folder and at it's best sorted alphanumerical. The output can then be redirectet to a file.

Whats happening here?

:

That's the true function in bash. This mostly is used for no-ops as it returns just true.

|

Thats a pipe, which takes the output of the left command and pipes it in the input of the right command.

$(sed $"s/\s/ - - /g" <<< $(ls -1|paste -sd" " -))

This just builds the line that is needed for paste. It will look something like

file1 - - file2 - - file3 - - file4 ...

So when paste is called it will write all lines from the listed files to standard output. When a file isn't found or called "-" paste reads from standard input and get's the TRUE value from : which is piped into paste.

Normally every file is appended a tab operator after is has been written to stdout. with the -d"\n" argument for paste the tab is exchanged with a newline.

So now paste writes the files seperated with newlines to stdout and when paste finds a "-" it takes the true and only writes the seperator to stdout - the newline.

  • For some reason, this one did not work for me on MacOS Mojave, even though it worked on my Linux system. I can't figure out why, though. – Soren Bjornstad Mar 01 '19 at 13:08
1
printf '\n\n' | cat file1.md - file2.md

Something like cuonglm's, I think. Aspiring to it, anyway.

mikeserv
  • 58,310
  • The only downside with this (and cuonglm's) - I think - is when you need to concatenate many files (e.g 20 files) as you'll have to build up the command line args. Or when trying to concatenate all *.md's in a dir... – don_crissti Jun 29 '15 at 19:26
  • @don_crissti - Yeah, i was just thinking about that. It's not an aspect which immediately occurred to me, but i was just thinking about it. It's not so hard with the shell if you can couch it in a function where it get's it's own arg array, cause then you can just use eval with some genned string like $1 - $2 -... and so on. but still inconvenient. I wonder about sed r\ file file or something... it's worth chewing on. – mikeserv Jun 29 '15 at 19:33
0

Not the best solution but works for your case:

echo -e `cat file1.md`"\n\n"`cat file2.md`
shivams
  • 4,565
  • I was hoping for something more Unix-like which would simply accept multiple files and join them with a given delimiter. – Naftuli Kay May 19 '15 at 00:26
  • I am not able to think of any Unix-like solution which would simply accept files and join them with a given delimiter. Perhaps, you could write a small shell function for this. – shivams May 19 '15 at 00:32
0

With a newer GNU awk:

awk '1; ENDFILE {print "\n"}' files...
Janis
  • 14,222