これは、なにをしたくて書いたもの?
YAMLで複数行の文字列を書く方法をちゃんと把握していなかったので、メモとして。
YAMLの仕様書
YAMLの仕様書を確認しましょう。
あんまり気にしたことがなかったのですが、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で複数行の文字列を扱う方法を見てみました。
このあたり、ちゃんと見てきていなかったのでいろいろと仕様があって驚きました。
意味をわかって使うようにしないとですねぇ…。