CLOVER🍀

That was when it all began.

YAMLで複数行の文字列を入力したい

これは、なにをしたくて書いたもの?

YAMLで複数行の文字列を書く方法をちゃんと把握していなかったので、メモとして。

YAMLの仕様書

YAMLの仕様書を確認しましょう。

The Official YAML Web Site

あんまり気にしたことがなかったのですが、YAMLの仕様は1.2(1.2.2)なんですね。

YAML Ain’t Markup Language (YAML™) revision 1.2.2

読むのはこのあたりですね。

YAML Ain’t Markup Language version 1.2 / Block Style Productions / Block Scalar Styles

  • Block Scalar Headers
    • Block Indentation Indicator(未指定、または1〜9) … コンテンツのインデントレベルを制御する
    • Block Chomping Indicator(-`、+`) … コンテンツの最後の改行と空白の解釈方法を制御する
  • Literal Style(|) … 空白を含むすべての文字がコンテンツとして解釈されるが、改行文字は正規化される
  • Folded Style(>) … 改行をスペースにして折り返しのコンテンツとして解釈する

実際の例を見た方がわかりやすいと思うのと、Literal Style、Folded Styleから見ていった方がいいかなと思うので、
サンプルを作って見ていきます。

環境

今回の環境はこちら。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.3 LTS
Release:        24.04
Codename:       noble


$ uname -srvmpio
Linux 6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

yqを使う

確認にはyqを使うことにします。

$ sudo apt install yq

aptでインストールされるyqは、こちらのようです。

$ apt show yq
Package: yq
Version: 3.1.0-3
Priority: optional
Section: universe/utils
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian Python Team <team+python@tracker.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 70.7 kB
Depends: jq, python3-argcomplete, python3-toml, python3-xmltodict, python3-yaml, python3:any
Homepage: https://github.com/kislyuk/yq
Download-Size: 16.9 kB
APT-Manual-Installed: yes
APT-Sources: http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages
Description: Command-line YAML processor - jq wrapper for YAML documents
 yq transcodes YAML documents to JSON and passes them to jq. The
 package also includes xq, which transcodes XML to JSON using
 xmltodict and pipes it to jq, and tomlq, which uses the toml library
 to transcode TOML to JSON, then pipes it to jq

GitHub - kislyuk/yq: Command-line YAML, XML, TOML processor - jq wrapper for YAML/XML/TOML documents

Literal Style

まずはLiteral Styleから見ていきましょう。Literal Styleでは|を使うことで、複数行の文字列を表現できます。

ここにBlock Chomping Indicatorを組み合わせたものを例として書いてみます。

literal.yaml

foo:
  literal_clip: |
    Java
    Python
    Node.js


  literal_strip: |-
    Java
    Python
    Node.js


  literal_keep: |+
    Java
    Python
    Node.js

なにも指定しないのがClipというBlock Chomping Indicatorで、最後の改行はコンテンツに保持されますが、末尾の空白は
除去されます。
-はStripというBlock Chomping Indicatorで、最後の改行と末尾の空白はコンテンツから除去されます。
+はKeepというBlock Chomping Indicatorで、最後の改行と末尾の空白も含めてコンテンツに残します。

yqで確認してみましょう。

Literal Style+Clip。

$ yq -r .foo.literal_clip literal.yaml
Java
Python
Node.js

-rは改行やクォートをエスケープなしで出力するオプションです。外すとこういう感じになります。

$ yq .foo.literal_clip literal.yaml
"Java\nPython\nNode.js\n"

末尾の改行がそのまま残っていますね。

Literal Style+Strip。

$ yq -r .foo.literal_strip literal.yaml
Java
Python
Node.js

Literal Style+Keep。

$ yq -r .foo.literal_keep literal.yaml
Java
Python
Node.js

ちょっとわかりにくいので、-rを外してみます。

$ yq .foo.literal_keep literal.yaml
"Java\nPython\nNode.js\n\n"

改行がそのまま残っていることがわかります。

Folded Style

Folded Styleは、>を使うことでコンテンツの折り返しを表現します。

Block Chomping Indicatorと組み合わせて、実際の内容を見てみましょう。

fold.yaml

foo:
  fold_clip: >
    Java
    Python
    Node.js


  fold_strip: >-
    Java
    Python
    Node.js


  fold_keep: >+
    Java
    Python
    Node.js

Folded Style+Clip。

$ yq -r .foo.fold_keep fold.yaml
Java Python Node.js

ちょっとびっくりします。-rを外してみましょう。

$ yq .foo.fold_keep fold.yaml
"Java Python Node.js\n\n"

コンテンツ内の改行は空白に置き換わり、末尾の改行も空白も残るのでこういう動作になるようです。

Folded Style+Strip。

$ yq -r .foo.fold_strip fold.yaml
Java Python Node.js

改行がなくなりました。

Folded Style+Keep。

$ yq -r .foo.fold_keep fold.yaml
Java Python Node.js

-rを外してみましょう。

$ yq .foo.fold_keep fold.yaml
"Java Python Node.js\n\n"

今回の場合、Clipと差がわかりにくいですね…。

Block Indentation Indicator?

最後にBlock Indentation Indicatorに触れておきます。

Block Indentation IndicatorはLiteral StyleやFolded Styleのインジケーターの後に数字を指定することで、コンテンツの
インデントレベルをコントロールできます。

下の例でいうと、「1」がBlock Indentation Indicatorです。

indent.yaml

indent.yaml
foo:
  literal: |
    Java
    Python
    Node.js


  literal_indent: |1
    Java
    Python
    Node.js

こういう結果になります。

Block Indentation Indicatorなし。

$ yq -r .foo.literal indent.yaml
Java
Python
Node.js

Block Indentation Indicatorあり。

$ yq -r .foo.literal_indent indent.yaml
 Java
 Python
 Node.js

1を入れたので、インデントレベルが1になりました。

Block Indentation Indicatorをなにも指定しないと、コンテンツの先頭を基準にインデントレベルが調整されるようです。

おわりに

YAMLで複数行の文字列を扱う方法を見てみました。

このあたり、ちゃんと見てきていなかったのでいろいろと仕様があって驚きました。
意味をわかって使うようにしないとですねぇ…。