Bash Script to convert Hugo Content Files to Page Bundles

Here is a bash script to quickly convert your Content Files to Page Bundles (introduced today with Hugo 0.32)

The following script will convert every markdown into a folder that contains an index.md like so:

for FILE in *.md
do
  # remove the last dot and subsequent chars to name the folder from the .md
  DIR="${FILE%.*}"
  mkdir -p "$DIR"
  mv "$FILE" "$DIR"
done
find ./ -iname '*.md' -execdir mv -i '{}' index.md \;

Save the above script into something like dir-from-files.sh make it executable and simply run with

./dir-from-files.sh

Happy New Year everybody! :boom:

13 Likes

I tried this. didn’t work for me. Can you assist me?

This script is for Linux. If you are on Windows I can’t help. If you’re on MacOs I think that iname is not available and you need a workaround. But I can’t help with that either I’m afraid.

Maybe someone who uses a Mac or Windows could chime in and help.

I use Linux. Ubuntu to be precise. maybe i;m doing something wrong

1 Like

It works on mac fine, thanks @alexandros

However, FYI, it does not handle a section folder like content/post/somepost.md. That just gets converted to content/post/index.md. Not quite sure how to fix it.

1 Like

Hm… good to know it’s working on the Mac. I thought it wouldn’t… LOL!

But the script is meant for be used in a folder full of .md files and the .sh should be in the same directory also.

We’re on the same distro. (high five!)

So can you tell me what you’ve tried so far? Are you getting any errors in the terminal?

It’s a simple little script, meant to be saved as a .sh then you need to make into an executable (see here for instructions)

Then you simple put your .md files into the same directory as the executable, open terminal from that folder and simply run ./dir-from-files.sh

Yaay. Apparently, I’m trying to convert data files and not content files. I got these errors
dir-from-files.sh: line 3: syntax error near unexpected tokenDIR="${FILE%.*}"' dir-from-files.sh: line 3: DIR="${FILE%.*}"

What is the extension of the data files? I think that if you replace .md with what you’re using the script should work.

But I haven’t tried that…

It’s .toml I tried that didn’t work for me.

OK. I just tested the script with .toml and to get it working you need to modify it like this:

for FILE in *.toml
do
  # remove the last dot and subsequent chars, then add new ext
  DIR="${FILE%.*}"
  mkdir -p "$DIR"
  mv "$FILE" "$DIR"
done
find ./ -iname '*.toml' -execdir mv -i '{}' index.md \;
1 Like

Thanks this worked.

Just used this script on a big folder … Works great! Thanks!

2 Likes

@alexandros I can’t thank you enough, the script didn’t do all the magic but resolved a mess of 3,584 changed files with 13,242 additions and 15,833 deletions. :slight_smile:

3 Likes

:+1:

Thanks a lot for this bash script.

1 Like

For Windows:

forfiles /m *.md /c "cmd /c md @fname"
forfiles /m *.md /c "cmd /c move @file @fname\"

or change the las tline to

forfiles /m *.md /c "cmd /c move @file @fname\index.md"

1 Like

For Windows Useful cmd for windows-users. Converter page.md to page/index.md and reverse; slug to filename and etc

1 Like

I’m on a mac, and used this variant for individual sets of files:

#!/bin/bash
# Assumes bilingual files like name.lang.md
# Get the first argument which should be just the base filename
for FILE in $1*.md
do
  # get basename from .md file to make folder
  DIR="${FILE%.*.*}"
  # get name with lang
  LANGPRE="${FILE%.*}"
  # get lang string
  LANG="${LANGPRE##*.}"

  # make the folder
  mkdir -p "$DIR"
  # move the files into the folder and rename
  mv "$FILE" "$DIR/index.$LANG.md"

done
ls -la "$DIR"

You might notice it will do the mkdir for every loop, which is not needed but, because of the -p switch, the folder gets created on only the first iteration. So it creates it the first loop, then fails to create it on subsequent loops. It’s an assumption but, probably good enough.

I put that in a file bundle.sh in my content/pages folder, and set it to executable with:

> chmod +x bundle.sh

Then assuming there are two files like about.en.md and about.ja.md, I ran it like this:

> ./bundle.sh about

For more info on how this is working, look into “bash parameter substitution”.

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

If you are editing the script and want to figure out a variant, start out with echo instead of the mkdir and mv commands, so that you can see how the script is working. Like:

echo $DIR
echo $LANGPRE
etc
4 Likes