I just spent the evening trying to parse a YAML Front Matter from bash. It requires to have yq installed. Here is the code:


function main() {
  filepath=$1
  project_name=$(get_project_name_from_path ${filepath})
  echo -e "${project_name}"
}

function get_project_name_from_file() {
  file_path=$1
  yaml_front_matter=$(get_yaml_front_matter $file_path)
  if [[ $? == 0 ]]; then
    # Case YAML Front Matter exists
    fdebug "yaml_front_matter:\n\n ${yaml_front_matter}"
    yaml_project_name=$( get_project_name_from_yaml "${yaml_front_matter}" )
    if [[ $? == 0 ]]; then
      # Case YAML Front Matter defines a project name
      fdebug "YAML Front Matter defines a project name"
      project_name=${yaml_project_name}
      return_value=0
    else
      # Case YAML Front Matter DOES NOT defines a project name
      fdebug "YAML Front Matter DOES NOT defines a project name"
      project_name=$( get_end_of_path ${project_path} ) # Return folder name as project name
      return_value=2
    fi
    fdebug "Returned \$yaml_project_name : $yaml_project_name"
  else
    # Case YAML Front Matter DOES NOT exists
    fdebug "YAML Front Matter DOES NOT exists"
    project_name=$( get_end_of_path ${project_path} ) # Return folder name as project name
    return_value=1
  fi

  echo ${project_name}
  return ${return_value}
}


function get_yaml_front_matter() {
  file_path=$1
  file_start=$( \head -n 1 $file_path )
  if [[ $file_start == "---" ]]; then
    # Case there might be a YAML Front Matter
	  while IFS='' read -r line; do # IFS='' to keep whitespaces
      # Check end of YAML Front Matter
      ( echo $line | grep -- '---' &>/dev/null ) && yaml_front_matter_validated="true" && break

      yaml_front_matter="${yaml_front_matter}${line}\n"

		done < <( \tail -n +2 $file_path ) # Skip first line containing ---

    if [[ $yaml_front_matter_validated == "true" ]]; then
      # Case there is a YAML Front Matter
      echo "${yaml_front_matter}"
    else
      # Case there is NO VALID a YAML Front Matter
      return 1
    fi

	else
    # Case there is NO YAML Front Matter
    return 1
	fi

}

function get_project_name_from_yaml() {
  yaml_front_matter=${1}

  yaml_project_name=$(echo -e $yaml_front_matter | yq -r .project.name) # -r: no color, no quotes

  if [[ $yaml_project_name != 'null' ]]; then
    # Case project.name value exists
    echo $yaml_project_name
    return 0
  else
    # Case project.name value DOES NOT exist
    return 1
  fi

}

function get_end_of_path() {
  path=$1
  echo ${path##*/}
}

function get_end_of_path() {
  path=$1
  echo ${path##*/}
}

function fdebug() {
  # Function debug: skips escaped characters
  msg=$1
  [[ $DEBUG == "true" ]] && echo -n "DEBUG: ${msg}\n"
}

main $@

It think it’s possible to design a better abstraction layer, but this format suited the issue I was trying to resolve. Something like get_yfm_entity <filename> <filter> would be more generalist

NB: There must be better ways to debug, but this worked for me at this moment.