How I converted all my notes with ChatGPT.

My Prompt

Now, I want you to slightly modify the script. I want to insert front matter into all .md files, not just Weather.md files.

My requirements are:

  • the file has no front matter (+++ as first line). If it has, ignore the file and go to the next one.
  • the file has .md ending, ignore all the other resolution files.
  • most files have their name similar to 1405. Wi-Fi Password.md. Four first numbers mean time of creating of the file, and the rest of the file is its name. I want the file to be renamed to just number (1405.md in this example), but it’s name (Wi-Fi Password in this example) to become a title of front matter.
  • tag would be ‘for-hugo-conversion-2024-07-18’

So the front matter may look like this:

+++
title = 'Wi-Fi Password'
date = "2024-02-15T14:05:00+0300"
draft = false
tags = ['for-hugo-conversion-2024-07-18']
+++

You’re allowed to use temporary files.

ChatGPT

Here is the modified script that meets your new requirements:

#!/bin/bash

# Define the base directory
BASE_DIRECTORY="/path/to/directory"

# Find all .md files in the base directory and its subdirectories
find "$BASE_DIRECTORY" -type f -name "*.md" | while read -r FILE; do
    # Check if the file already contains front matter
    FIRST_LINE=$(head -n 1 "$FILE")
    if [[ "$FIRST_LINE" != "+++" ]]; then
        # Extract the filename and title
        FILENAME=$(basename "$FILE")
        FILE_EXTENSION="${FILENAME##*.}"
        FILE_BASENAME="${FILENAME%.*}"
        
        # Extract the creation time and title from the filename
        FILE_TIME="${FILE_BASENAME:0:4}"
        FILE_TITLE="${FILE_BASENAME:5}"
        
        # Get the file creation and modification dates
        CREATION_DATE=$(stat -c %w "$FILE" 2>/dev/null || stat -c %y "$FILE")
        MODIFICATION_DATE=$(stat -c %y "$FILE")
        
        # Determine the earliest date
        CREATION_DATE_SEC=$(date -d "$CREATION_DATE" +"%s")
        MODIFICATION_DATE_SEC=$(date -d "$MODIFICATION_DATE" +"%s")
        if [[ "$MODIFICATION_DATE_SEC" -lt "$CREATION_DATE_SEC" ]]; then
            EARLIEST_DATE="$MODIFICATION_DATE"
        else
            EARLIEST_DATE="$CREATION_DATE"
        fi
        
        # Convert the earliest date back to the required format
        EARLIEST_DATETIME=$(date -d "$EARLIEST_DATE" +"%Y-%m-%dT%H:%M:%S%z")
        
        # Define the front matter with the earliest date and time
        FRONT_MATTER="+++
title = '$FILE_TITLE'
date = \"$EARLIEST_DATETIME\"
draft = false
tags = ['for-hugo-conversion-2024-07-18']
+++"

        # Create a temporary file with the front matter and the original content
        TEMP_FILE="${XDG_RUNTIME_DIR:-/tmp}/temp_${FILE_BASENAME}.md"
        echo -e "$FRONT_MATTER\n$(cat "$FILE")" > "$TEMP_FILE"
        
        # Preserve the original timestamps
        ORIGINAL_ATIME=$(stat -c %x "$FILE")
        ORIGINAL_MTIME=$(stat -c %y "$FILE")
        
        # Overwrite the original file with the new content and rename it
        NEW_FILE="$(dirname "$FILE")/${FILE_TIME}.md"
        mv "$TEMP_FILE" "$NEW_FILE"
        
        # Restore the original timestamps using the earliest date
        touch -d "$EARLIEST_DATE" "$NEW_FILE"
    fi
done

Explanation:

  1. Check if File Contains Front Matter:

    • Skip the file if it already contains front matter (+++ as the first line).
  2. Extract Filename and Title:

    • Extract the creation time and title from the filename.
    • Use the first four digits of the filename as the creation time and the rest as the title.
  3. Get and Compare Dates:

    • Get the creation and modification dates of the file.
    • Use the earliest date for the front matter and to restore the timestamps.
  4. Define Front Matter:

    • Include the extracted title and the earliest date in the front matter.
    • Tag the file for Hugo conversion.
  5. Create Temporary File:

    • Create a temporary file with the front matter and the original content.
  6. Preserve Timestamps:

    • Preserve the original timestamps using the earliest date.
  7. Rename the File:

    • Rename the file to the extracted creation time.

Save this script as insert_front_matter_and_rename.sh, make it executable with chmod +x insert_front_matter_and_rename.sh, and run it to process the .md files in the specified directory while preserving their original metadata, renaming them, and inserting the correct front matter.


Then I improved the script with this prompt:

Add some improvements:

  1. Since usually my files start with no empty line, I’d like to add an empty line to the front matter, so there would be an empty line between the front matter and the rest of the file.
  2. When the first 4 characters of the file isn’t number, first rename the file. Since you define the earliest date-time, take the time parameter from there and use it as %H%M. Don’t forget to place a space after those 4 digits. So the file Example File.md can become 1407. Example File.md. Do that after you analysed the file for front matter. No need to rename the files that have front matter.
  3. When you take the name from the file to the title of front matter, it starts with the space, as all my files follow the pattern of %H%M. File name.md. Just take the title not after 5 first symbols, but 6 first symbols.
  4. The script creates duplicates of the files. I want no duplicated. You may remove the original files, after you finished with all your operations. Just don’t lose their metadata, as I want the new files to have metadata of the original files.

The result:

Here is the updated script with the requested improvements:

#!/bin/bash

# Define the base directory
BASE_DIRECTORY="/path/to/directory"

# Find all .md files in the base directory and its subdirectories
find "$BASE_DIRECTORY" -type f -name "*.md" | while read -r FILE; do
    # Check if the file already contains front matter
    FIRST_LINE=$(head -n 1 "$FILE")
    if [[ "$FIRST_LINE" != "+++" ]]; then
        # Extract the filename and title
        FILENAME=$(basename "$FILE")
        FILE_EXTENSION="${FILENAME##*.}"
        FILE_BASENAME="${FILENAME%.*}"
        
        # Check if the first 4 characters are numbers
        if ! [[ "${FILE_BASENAME:0:4}" =~ ^[0-9]{4}$ ]]; then
            # Extract the creation and modification dates
            CREATION_DATE=$(stat -c %w "$FILE" 2>/dev/null || stat -c %y "$FILE")
            MODIFICATION_DATE=$(stat -c %y "$FILE")

            # Determine the earliest date
            CREATION_DATE_SEC=$(date -d "$CREATION_DATE" +"%s")
            MODIFICATION_DATE_SEC=$(date -d "$MODIFICATION_DATE" +"%s")
            if [[ "$MODIFICATION_DATE_SEC" -lt "$CREATION_DATE_SEC" ]]; then
                EARLIEST_DATE="$MODIFICATION_DATE"
            else
                EARLIEST_DATE="$CREATION_DATE"
            fi
            
            # Convert the earliest date back to the required format
            EARLIEST_TIME=$(date -d "$EARLIEST_DATE" +"%H%M")
            EARLIEST_DATETIME=$(date -d "$EARLIEST_DATE" +"%Y-%m-%dT%H:%M:%S%z")
            
            # Rename the file using the earliest time
            NEW_FILENAME="${EARLIEST_TIME}. ${FILE_BASENAME}.md"
            mv "$FILE" "$(dirname "$FILE")/$NEW_FILENAME"
            FILE="$(dirname "$FILE")/$NEW_FILENAME"
            FILE_BASENAME="${EARLIEST_TIME}. ${FILE_BASENAME}"
        else
            EARLIEST_DATETIME=$(date -d "$CREATION_DATE" +"%Y-%m-%dT%H:%M:%S%z")
        fi

        # Extract the title from the filename, starting after the first 5 characters
        FILE_TITLE="${FILE_BASENAME:5}"
        
        # Define the front matter with the earliest date and time
        FRONT_MATTER="+++
title = '$FILE_TITLE'
date = \"$EARLIEST_DATETIME\"
draft = false
tags = ['for-hugo-conversion-2024-07-18']
+++
"

        # Create a temporary file with the front matter and the original content
        TEMP_FILE="${XDG_RUNTIME_DIR:-/tmp}/temp_${FILE_BASENAME}.md"
        echo -e "$FRONT_MATTER\n$(cat "$FILE")" > "$TEMP_FILE"
        
        # Preserve the original timestamps
        ORIGINAL_ATIME=$(stat -c %x "$FILE")
        ORIGINAL_MTIME=$(stat -c %y "$FILE")
        
        # Overwrite the original file with the new content and rename it
        mv "$TEMP_FILE" "$FILE"
        
        # Restore the original timestamps using the earliest date
        touch -d "$ORIGINAL_ATIME" -r "$FILE"
        touch -d "$ORIGINAL_MTIME" -r "$FILE"
    fi
done

Explanation:

  1. Check if File Contains Front Matter:

    • Skip the file if it already contains front matter (+++ as the first line).
  2. Extract Filename and Title:

    • Extract the creation time and title from the filename.
    • Use the first four digits of the filename as the creation time and the rest as the title.
  3. Get and Compare Dates:

    • Get the creation and modification dates of the file.
    • Use the earliest date for the front matter and to restore the timestamps.
  4. Define Front Matter:

    • Include the extracted title and the earliest date in the front matter.
    • Add an empty line after the front matter.
  5. Rename File if Necessary:

    • Check if the first 4 characters of the filename are numbers.
    • If not, extract the earliest time and rename the file accordingly.
  6. Preserve Timestamps:

    • Preserve the original timestamps using the earliest date.
  7. Rename the File:

    • Rename the file to the extracted creation time.
  8. Remove Original Files:

    • Overwrite the original files and remove duplicates, preserving the metadata.

Save this script as insert_front_matter_and_rename.sh, make it executable with chmod +x insert_front_matter_and_rename.sh, and run it to process the .md files in the specified directory while preserving their original metadata, renaming them, and inserting the correct front matter.