Content files in Hugo are written in Markdown, and look like this:
---
title: hello
tags: fruits
---
Here is an article about **fruits**
When you switch to a new theme or migrate content, you need to edit the Front Matter of multiple files.
We can make use of 
Yq, a standalone executable providing batch Front Matter edition from the terminal.
YAML, JSON and XML are supported, and 
binaries are available for Linux, Mac, FreeBSD and Windows.
As an example, here is how to bulk edit tags: from every Markdown files:
find -name  "*.md" -exec yq '.tags = "food"' -i {} \;
Basic examples are missing in the offical documentation, so here is a memo.
First, let’s read the files
Here is how to extract the title: variable from example.md
yq '.title' example.md
Get title: from multiple files:
yq '.title' fruits.md example.md
(Hint: Separator --- can be removed with --no-doc)
Get every .md files and show title
find -name  "*.md" -exec yq '.title'  {} \;
Now let’s update our files
Starting gently with a single file
Let’s imagine that we want to modify the tags variable.
Run a test
yq '.tags = "food"' example.md
Write the file with -i
yq '.tags = "food"' example.md -i
Note: special characters must be escaped:
yq '.title = "This is a \"special\" update"' example.md -i
See the documentation for advanced guidance on special characters.
Batch modifications
Preview the modifications with a test run:
find -name  "*.md" -exec yq '.tags = "food"' {} \;
Add -i to apply
find -name  "*.md" -exec yq '.tags = "food"' -i {} \;
Solving the error “bad file mapping values are not allowed”
You may get messages like “Error: bad file .. mapping values are not allowed in this context”
In such situation, use --front-matter="process" like this:
find -name  "*.md" -exec yq --front-matter="process" '.tags = "food"' -i {} \;
Note: this will also fix/change the indentation of your Front Matter.
Other nice features
yq also provides the following features:
Convert YAML file to JSON
yq config.yml -o json
Convert YAML file to XML
yq config.yml -o xml
Create a new file with custom content
yq -n '.title="A new post"' > new.yml
Note: Front matter separator --- are not added to new files.
Combine multiple Yaml files into one
yq '.' folder/*.yml
Use conditionals with if / else
See this hidden corner of the doc
The complete man page
$ yq --help
yq is a portable command-line YAML processor (https://github.com/mikefarah/yq/) 
See https://mikefarah.gitbook.io/yq/ for detailed documentation and examples.
Usage:
  yq [flags]
  yq [command]
Examples:
# yq defaults to 'eval' command if no command is specified. See "yq eval --help" for more examples.
# read the "stuff" node from "myfile.yml"
yq '.stuff' < myfile.yml
# update myfile.yml in place
yq -i '.stuff = "foo"' myfile.yml
# print contents of sample.json as idiomatic YAML
yq -P sample.json
Available Commands:
  completion       Generate the autocompletion script for the specified shell
  eval             (default) Apply the expression to each document in each yaml file in sequence
  eval-all         Loads _all_ yaml documents of _all_ yaml files and runs expression once
  help             Help about any command
  shell-completion Generate completion script
Flags:
  -C, --colors                        force print with colors
  -e, --exit-status                   set exit status if there are no matches or null or false is returned
      --expression string             forcibly set the expression argument. Useful when yq argument detection thinks your expression is a file.
      --from-file string              Load expression from specified file.
  -f, --front-matter string           (extract|process) first input as yaml front-matter. Extract will pull out the yaml content, process will run the expression against the yaml content, leaving the remaining data intact
      --header-preprocess             Slurp any header comments and separators before processing expression. (default true)
  -h, --help                          help for yq
  -I, --indent int                    sets indent level for output (default 2)
  -i, --inplace                       update the file inplace of first file given.
  -p, --input-format string           [yaml|y|props|p|xml|x] parse format for input. Note that json is a subset of yaml. (default "yaml")
  -M, --no-colors                     force print with no colors
  -N, --no-doc                        Don't print document separators (---)
  -n, --null-input                    Don't read input, simply evaluate the expression given. Useful for creating docs from scratch.
  -o, --output-format string          [yaml|y|json|j|props|p|xml|x] output format type. (default "yaml")
  -P, --prettyPrint                   pretty print, shorthand for '... style = ""'
  -s, --split-exp string              print each result (or doc) into a file named (exp). [exp] argument must return a string. You can use $index in the expression as the result counter.
      --split-exp-file string         Use a file to specify the split-exp expression.
  -r, --unwrapScalar                  unwrap scalar, print the value with no quotes, colors or comments (default true)
  -v, --verbose                       verbose mode
  -V, --version                       Print version information and quit
      --xml-attribute-prefix string   prefix for xml attributes (default "+")
      --xml-content-name string       name for xml content (if no attribute name is present). (default "+content")
      --xml-keep-namespace            enables keeping namespace after parsing attributes (default true)
      --xml-raw-token                 enables using RawToken method instead Token. Commonly disables namespace translations. See https://pkg.go.dev/encoding/xml#Decoder.RawToken for details. (default true)
      --xml-strict-mode               enables strict parsing of XML. See https://pkg.go.dev/encoding/xml for more details.
Use "yq [command] --help" for more information about a command.
Further reading
- Official documentation
- Handle Dates
- Navigate structured Yaml files
- Advanced usage
- Introduction to Yaml
Other tools
- A bash script to add front matter to a bunch of Markdown files
- https://github.com/tomwright/dasel
- https://github.com/pandastrike/yaml-cli
- Written in Python:
- NPM based editors
- https://chrisdmacrae.github.io/front-matter-manipulator (unmaintained)
- https://github.com/hilja/file-batcher (unmaintained)
- https://github.com/dworthen/js-yaml-front-matter (unmaintained)
 
- Jinja: https://karlredman.github.io/EditFrontMatter/
- A collection: Frontmatter Tools