YAML Multiline Strings With Pipe and Greater Than Signs
The pipe keeps line breaks, the greater than sign folds them, and chomping indicators control the final newline. Six variants and the exact strings.

Real configuration contains text that does not fit on a line: a shell script in a CI step, a SQL query, a PEM certificate, a long description. YAML has two block styles for this, written with a pipe or a greater than sign after the key, and a small modifier that controls what happens to the final line break. Learning the six combinations once saves a lot of trial and error. All the strings below are the exact output of a parser.
The two styles
**Literal style, |.** Every line break in the block is kept. What you write is what you get, minus the indentation.
**Folded style, >.** Single line breaks become spaces, so the block reads as one long line. A blank line becomes a line break, which is how you separate paragraphs.
Both take the content from the lines that are indented more than the key, starting with the line after the indicator. The first non-empty line sets the indentation of the block, and the block ends at the first line that is indented less.
The test text, with the key k:
k: |
line one
line two
line four
next: 1The six variants
The text is the same in each case. Only the indicator changes. The Python strings that came out:
| 'line one\nline two\n\nline four\n'
|- 'line one\nline two\n\nline four'
|+ 'line one\nline two\n\nline four\n\n'
> 'line one line two\nline four\n'
>- 'line one line two\nline four'
>+ 'line one line two\nline four\n\n'Read it in two directions.
Across styles. The pipe keeps line one, line two, the blank line and line four as written, with \n between each. The greater-than style joined the first two lines with a space (line one line two) and turned the blank line into one \n, then continued with line four. That is the folding rule: a single newline between two non-empty lines becomes a space, and a blank line becomes a newline.
Across the chomping modifier. After the style indicator you may put a chomping indicator, which says what to do with the line break at the end and any blank lines after it:
No modifier (clip): keep exactly one final newline. This is the default and what most scripts want.
**
-(strip):** remove the final newline. The string ends withline fourand nothing else.**
+(keep):** keep the final newline and every blank line after it. Here two\nat the end, because one blank line followed the text before the next key.
The difference between clip and strip matters in practice. A shell command from run: | ends in a newline, which is normal. A value you will compare with another string, such as an expected output or a name, should use |- or >- to avoid a trailing newline that breaks the comparison.
Plain and quoted multiline strings
You can also continue a plain or quoted scalar across lines without any indicator:
k: first
second
third'first second third'Continuation lines are folded with spaces, the same rule as the greater-than style. This works for long descriptions, and it is fragile: the continuation lines must be indented more than the key, and a line that contains : or # breaks it. In double-quoted strings, a backslash at the end of a line joins without a space. Block style with an explicit indicator is clearer for anything over one line.
Indentation is content
Inside a block scalar the leading spaces matter. The first non-empty line decides the base indentation, and extra indentation on later lines is kept:
script: |
if true; then
echo "nested"
fiThe string has two spaces before echo, preserving the shell's formatting. In folded style, lines that are more indented than the base are not folded: they keep their line breaks, which is useful for code samples inside prose and surprising otherwise.
If the first line of the block is itself indented more than the lines that follow, the parser cannot know which indentation you meant, and you must give it an explicit indentation indicator, a digit after the style (|2). This is rare. The usual mistake is a tab or inconsistent spaces in the block, which gives a parse error (finding tab characters hiding in a YAML file).
Trailing spaces at the end of lines inside a literal block are preserved, invisibly. A script with a trailing space after a backslash line continuation breaks in the shell, and the YAML looks fine. Turn on trailing-whitespace trimming in your editor, and lint (linting YAML with yamllint).
Choosing
| Content | Use | Why |
|---|---|---|
| Shell script, SQL, code | | | Line breaks are meaningful |
| Certificate or key | | | The line structure is part of the format |
| Long description or message | > or >- | One logical line, wrapped for readers |
| Text compared with something | |- or >- | No trailing newline |
| Paragraphs | > with blank lines | Blank line becomes a paragraph break |
| One short line | Plain or quoted | No block needed |
And two cautions. A literal block is not a template: it does not expand variables, so $HOME inside a CI run: | step is passed to the shell as is, and the shell expands it. And a block scalar cannot have a comment on its content lines, since a # there is content. Put comments above the key.
Related reading
The cluster hub is YAML syntax you need to stop guessing at. For the rest of the scalar rules, see YAML strings, quoting and when you need quotes and the indentation basics in YAML indentation rules and why tabs break everything. The block scalars are specified in chapter 8 of the YAML 1.2.2 specification, and a visual reference at yaml-multiline.info. Check how a block loads in the YAML to JSON tool.
When block scalars are the wrong tool
The text is large or binary. A 40 KB certificate bundle or a base64 blob in the middle of a config file hides the structure. Put it in its own file and refer to the path.
The text needs interpolation. If values must be filled in, use a templating step after parsing, with the escaping rules of the target language (environment variable substitution in YAML config).
A tool rewrites the file. Some libraries save block scalars as quoted strings with escapes, destroying the readable layout. Use a round-trip library, or accept the churn (writing YAML from Python without ugly output).
The consumer needs exact bytes. Windows line endings, tabs and trailing spaces do not survive an editor reliably. Encode the exact content in a separate file.


