Updated
OK, here's a (still) rough (but now working) script (thanks @riccardo for the access to a test Org):
#!/usr/bin/env bash
: "${ORGANIZATION:?Need to export ORGANIZATION and it must be non-empty}"
# gcloud format
FORMAT="csv[no-heading](name,displayName.encode(base64))"
# Enumerates Folders recursively
folders()
{
  LINES=("$@")
  for LINE in ${LINES[@]}
  do
    # Parses lines of the form folder,name
    VALUES=(${LINE//,/ })
    FOLDER=${VALUES[0]}
    # Decodes the encoded name
    NAME=$(echo ${VALUES[1]} | base64 --decode)
    echo "Folder: ${FOLDER} (${NAME})"
    folders $(gcloud resource-manager folders list \
      --folder=${FOLDER} \
      --format="${FORMAT}")
  done
}
# Start at the Org
echo "Org: ${ORGANIZATION}"
LINES=$(gcloud resource-manager folders list \
  --organization=${ORGANIZATION} \
  --format="${FORMAT}")
# Descend
folders ${LINES[0]}
I'm challenged to do this more effectively in Bash; I'm interested to see whether more experienced Bash users have suggestions.
The script uses a gcloud projection to base64 encode displayName values. This is a hacky way to avoid inadvertent parsing of these strings (they may contain spaces) and I was unable to find a way to escape these otherwise.
Still doesn't indent levels 😞
Previous
Super rough... and regrettably without access to either an Org or Folders so, mostly guessing...
#!/usr/bin/env bash
ORGANIZATION="..."
folders()
{
  for FOLDER in ${1}
  do
    echo ${FOLDER}
    # Use the `--folder` variant for children
    folders $(gcloud resource-manager folders list \
    --folder=${FOLDER} \
    --format="value(name)")
  done
}
# Start at the Org
echo "Org: ${ORGANIZATION}"
folders $(\
  gcloud resource-manager folders list \
  --organization=${ORGANIZATION} \
  --format="value(name)")
Various obvious issues (and likely many others)
- No error management
- Unclear what the returned format is and how to grab folderId
- No indenting of levels; I suspect you'd need to add an arg for this
- May need to convert the returned values into bash arrays
If you can provide the schema for gcloud resource-manager folders list ... --format=yaml, can try to address #2
You asked for gcloud but this may better done using e.g. Python