简体   繁体   中英

Bash: concatenate multiple files and add “\newline” between each?

I have a small Bash script that takes all Markdown files of a directory, and merge them into one like this:

for f in *.md; do (cat "${f}";) >> output.md; done

It works well. Now I'd like to add the string "\\newline" between each document, something like this:

for f in *.md; do (cat "${f}";) + "\newline" >> output.md; done

How can I do that? The above code obviously doesn't work.

If you want the literal string "\\newline" , try this:

for f in *.md; do cat "$f"; echo "\newline"; done > output.md

This assumes that output.md doesn't already exist. If it does (and you want to include its contents in the final output) you could do:

for f in *.md; do cat "$f"; echo "\newline"; done > out && mv out output.md

This prevents the error cat: output.md: input file is output file .

If you want to overwrite it, you should just rm it before you start.

You can do:

for f in *.md; do cat "${f}"; echo; done > output.md

You can add an echo command to add a newline. To improve performance I would recommend to move the write > outside the for loop to prevent reading and writing of file at every iteration.

Here's a funny possibility, using ed , the standard editor:

ed -s < <(
    for f in *.md; do
        [[ $f = output.md ]] && continue
        printf '%s\n' "r $f" a '\newline' .
    done
    printf '%s\n' "w output.md" "q"
)

(I've inserted a line to exclude output.md from the inserted files).

For each file:

  • r $f : r is ed 's insert file command,
  • a : ed starts a newline after the current line for editing,
  • \\newline : well, we're insertion mode, so ed just inserts this,
  • . : to stop insert mode.

At the end, we w rite the buffer to the file output.md and q uit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM