Josh Martin
Josh Martin

Reputation: 350

Generate code blocks in markdown by cat-ing over files

Hello I am trying to cat contents of files in a directory and append them to a markdown file as a code blocks.

I am able to cat the contents of the files to a markdown document but unable to add backticks to the markdown file. The backticks do not appear in the file. I can get backticks to print if I type printf "``" in my shell but not in the following bash script:

files=$(find . -name "*.h" -name "*.c" -maxdepth 1)

for i in $files;
do
    printf "\`\`" >> report.md
    cat $i >> report.md
    printf "\`\`" >> report.md
done


Upvotes: 1

Views: 682

Answers (1)

John Kugelman
John Kugelman

Reputation: 362187

That find statement won't actually find anything. There aren't any files named both *.h and *.c. You need -o for or:

find . -maxdepth 1 '(' -name "*.h" -o -name "*.c" ')'

The backticks should be in the output file, no reason they wouldn't be. That said, do you mean to have 3 of them? Normally Markdown uses 3 for code blocks. They should probably also be on separate lines.

for i in $files; do
    echo '```' >> report.md
    cat $i >> report.md
    echo '```' >> report.md
done

You could redirect the entire loop's output all at once.

for file in $files; do
    echo '```'
    cat "$file"
    echo '```'
done > report.md

For extra robustness I'd suggest using find -exec run the actions on each file. That way file names with spaces and other weird characters won't trip up the script.

find . -maxdepth 1 '(' -name "*.h" -o -name "*.c" ')' \
    -exec echo '```' ';' -exec cat {} ';' -exec echo '```' ';' > report.md

Or you could skip find altogether and simply loop over the desired files. This is also safe in the face of whitespace:

for file in *.h *.c; do
    echo '```'
    cat "$file"
    echo '```'
done > report.md

Upvotes: 2

Related Questions