Here documentIn computing, a here document (here-document, here-text, heredoc, hereis, here-string or here-script) is a file literal or input stream literal: it is a section of a source code file that is treated as if it were a separate file. The term is also used for a form of multiline string literals that use similar syntax, preserving line breaks and other whitespace (including indentation) in the text. Here documents originate in the Unix shell,[1] and are found in the Bourne shell since 1979, and most subsequent shells. Here document-style string literals are found in various high-level languages, notably the Perl programming language (syntax inspired by Unix shell) and languages influenced by Perl, such as PHP and Ruby. JavaScript also supports this functionality via template literals, a feature added in its 6th revision (ES6). Other high-level languages such as Python, Julia and Tcl have other facilities for multiline strings. Here documents can be treated either as files or strings. Some shells treat them as a format string literal, allowing variable substitution and command substitution inside the literal. OverviewThe most common syntax for here documents, originating in Unix shells, is The here document syntax is analogous to the shell syntax for input redirection, which is Other languages often use substantially similar syntax, but details of syntax and actual functionality can vary significantly. When used simply for string literals, the File literalsNarrowly speaking, here documents are file literals or stream literals. These originate in the Unix shell, though similar facilities are available in some other languages. Unix shellsHere documents are available in many Unix shells.[1] In the following example, text is passed to the $ LANG=C tr a-z A-Z << END
> one two three
> four five six
> END
ONE TWO THREE
FOUR FIVE SIX
In this case By default, behavior is largely identical to the contents of double quotes: variable names are replaced by their values, commands within backticks are evaluated, etc.[a] $ cat << EOF
> \$ Working dir "$PWD" `pwd`
> EOF
$ Working dir "/home/user" /home/user
This can be disabled by quoting any part of the label, which is then ended by the unquoted value;[b] the behavior is essentially identical to that if the contents were enclosed in single quotes. Thus for example by setting it in single quotes: $ cat << 'EOF'
> \$ Working dir "$PWD" `pwd`
> EOF
\$ Working dir "$PWD" `pwd`
Double quotes may also be used, but this is subject to confusion, because expansion does occur in a double-quoted string, but does not occur in a here document with double-quoted delimiter.[4] Single- and double-quoted delimiters are distinguished in some other languages, notably Perl (see below), where behavior parallels the corresponding string quoting. In POSIX shell but not csh/tcsh, appending a minus sign to the A script containing: LANG=C tr a-z A-Z <<- END_TEXT
Here doc with <<-
A single space character (i.e. 0x20 ) is at the beginning of this line
This line begins with a single TAB character i.e 0x09 as does the next line
END_TEXT
echo The intended end was before this line
echo and these were not processed by tr
echo +++++++++++++++
LANG=C tr a-z A-Z << END_TEXT
Here doc with <<
A single space character (i.e. 0x20 ) is at the beginning of this line
This line begins with a single TAB character i.e 0x09 as does the next line
END_TEXT
echo The intended end was before this line,
echo but because the line with the delimiting Identifier began with a TAB it was NOT recognized and
echo the tr command continued processing.
produces: HERE DOC WITH <<-
A SINGLE SPACE CHARACTER (I.E. 0X20 ) IS AT THE BEGINNING OF THIS LINE
THIS LINE BEGINS WITH A SINGLE TAB CHARACTER I.E 0X09 AS DOES THE NEXT LINE
The intended end was before this line
and these were not processed by tr
+++++++++++++++
HERE DOC WITH <<
A SINGLE SPACE CHARACTER (I.E. 0X20 ) IS AT THE BEGINNING OF THIS LINE
THIS LINE BEGINS WITH A SINGLE TAB CHARACTER I.E 0X09 AS DOES THE NEXT LINE
END_TEXT
ECHO THE INTENDED END WAS BEFORE THIS LINE,
ECHO BUT BECAUSE THE LINE WITH THE DELIMITING IDENTIFIER BEGAN WITH A TAB IT WAS NOT RECOGNIZED AND
ECHO THE TR COMMAND CONTINUED PROCESSING.
Another use is to output to a file: $ cat << EOF > ~/testFile001
> 3 spaces precede this text.
> A single tab character is at the beginning of this line.
>Nothing precedes this text
EOF
Here stringsA here string (available in bash, ksh, or zsh) is syntactically similar, consisting of A single word need not be quoted: $ LANG=C tr a-z A-Z <<< one
ONE
In case of a string with spaces, it must be quoted: $ LANG=C tr a-z A-Z <<< 'one two three'
ONE TWO THREE
This could also be written as: $ foo='one two three'
$ LANG=C tr a-z A-Z <<< "$foo"
ONE TWO THREE
Multiline strings are acceptable, yielding: $ LANG=C tr a-z A-Z <<< 'one
> two three'
ONE
TWO THREE
Note that leading and trailing newlines, if present, are included: $ LANG=C tr a-z A-Z <<< '
> one
> two three
> '
ONE
TWO THREE
$
The key difference from here documents is that, in here documents, the delimiters are on separate lines; the leading and trailing newlines are stripped. Unlike here documents, here strings do not use delimiters. Here strings are particularly useful for commands that often take short input, such as the calculator $ bc <<< 2^10
1024
Note that here string behavior can also be accomplished (reversing the order) via piping and the $ echo 'one two three' | LANG=C tr a-z A-Z
ONE TWO THREE
however here strings are particularly useful when the last command needs to run in the current process, as is the case with the $ echo 'one two three' | read -r a b c
$ echo "$a $b $c"
yields nothing, while $ read -r a b c <<< 'one two three'
$ echo "$a $b $c"
one two three
This happens because in the previous example piping causes Microsoft NMAKEIn Microsoft NMAKE, here documents are referred to as inline files. Inline files are referenced as target0: dependent0
command0 <<
temporary inline file
...
<<
target1: dependent1
command1 <<
temporary, but preserved inline file
...
<<KEEP
target2: dependent2
command2 <<filename2
named, but discarded inline file
...
<<NOKEEP
target3: dependent3
command3 <<filename3
named inline file
...
<<KEEP
RR does not have file literals, but provides equivalent functionality by combining string literals with a string-to-file function. R allows arbitrary whitespace, including newlines, in strings. A string then can be turned into a file descriptor using the str <-
"State Population Income Illiteracy Life.Exp Murder HS.Grad Frost
Alabama 3615 3624 2.1 69.05 15.1 41.3 20
Alaska 365 6315 1.5 69.31 11.3 66.7 152
Arizona 2212 4530 1.8 70.55 7.8 58.1 15
Arkansas 2110 3378 1.9 70.66 10.1 39.9 65"
x <- read.table(textConnection(str), header=TRUE, row.names=1)
Data segmentPerl[6] and Ruby[7] have a form of file literal, which can be considered a form of data segment. In these languages, including the line Data URI SchemeAs further explained in Data URI scheme, all major web browsers understand URIs that start with data: as here document. Multiline string literalsThe term "here document" or "here string" is also used for multiline string literals in various programming languages, notably Perl (syntax influenced by Unix shell), and languages influenced by Perl, notably PHP and Ruby. The shell-style Perl-influencedPerlIn Perl there are several different ways to invoke here docs.[8] The delimiters around the tag have the same effect within the here doc as they would in a regular string literal: For example, using double quotes around the tag allows variables to be interpolated, but using single quotes doesn't, and using the tag without either behaves like double quotes. Using backticks as the delimiters around the tag runs the contents of the heredoc as a shell script. It is necessary to make sure that the end tag is at the beginning of the line or the tag will not be recognized by the interpreter. Note that the here doc does not start at the tag—but rather starts on the next line. So the statement containing the tag continues on after the tag. Here is an example with double quotes: my $sender = "Buffy the Vampire Slayer";
my $recipient = "Spike";
print <<"END";
Dear $recipient,
I wish you to leave Sunnydale and never return.
Not Quite Love,
$sender
END
Output: Dear Spike,
I wish you to leave Sunnydale and never return.
Not Quite Love,
Buffy the Vampire Slayer
Here is an example with single quotes: print <<'END';
Dear $recipient,
I wish you to leave Sunnydale and never return.
Not Quite Love,
$sender
END
Output: Dear $recipient,
I wish you to leave Sunnydale and never return.
Not Quite Love,
$sender
And an example with backticks (may not be portable): my $shell_script_stdout = <<`END`;
echo foo
echo bar
END
It is possible to start multiple heredocs on the same line: say(<<BEGIN . "this is the middle\n" . <<END);
This is the beginning:
BEGIN
And now it is over!
END
# this is equivalent to:
say("This is the beginning:\nthis is the middle\nAnd now it is over!\n");
The tag itself may contain whitespace, which may allow heredocs to be used without breaking indentation. say <<' END';
Hello World
END
Although since Perl version 5.26,[9] heredocs can include indention: #prints "Hello there\n" with no leading whitespace.
if (1) {
print <<~EOF;
Hello there
EOF
}
In addition to these strings, Perl also features file literals, namely the contents of the file following PHPIn PHP, here documents are referred to as heredocs. In PHP heredocs are not string literals. Heredoc text behaves just like a double-quoted string, but without the double quotes. For example, meaning `$` will be parsed as a variable start, and `${` or `{$` as a complex variable start. <?php
$name = "Joe Smith";
$occupation = "Programmer";
echo <<<EOF
This is a heredoc section.
For more information talk to $name, your local $occupation.
Thanks!
EOF;
$toprint = <<<EOF
Hey $name! You can actually assign the heredoc section to a variable!
EOF;
echo $toprint;
?>
Outputs This is a heredoc section.
For more information talk to Joe Smith, your local Programmer.
Thanks!
Hey Joe Smith! You can actually assign the heredoc section to a variable!
In PHP versions prior to 7.3, the line containing the closing identifier must not contain any other characters, except an optional ending semicolon. Otherwise, it will not be considered to be a closing identifier, and PHP will continue looking for one. If a proper closing identifier is not found, a parse error will result at the last line of the script. However, from version 7.3, it is no longer required that the closing identifier be followed by a semicolon or newline. Additionally the closing identifier may be indented, in which case the indentation will be stripped from all lines in the doc string.[10] In PHP 5.3 and later, like Perl, it is possible to not interpolate variables by surrounding the tag with single quotes; this is called a nowdoc:[11] $x = <<<'END'
Dear $recipient,
I wish you to leave Sunnydale and never return.
Not Quite Love,
$sender
END;
In PHP 5.3+ it is also possible to surround the tag with double quotes, which like Perl has the same effect as not surrounding the tag with anything at all. RubyThe following Ruby code displays a grocery list by using a here document. puts <<GROCERY_LIST
Grocery list
----
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*
* Organic
GROCERY_LIST
The result: $ ruby grocery-list.rb
Grocery list
------------
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*
* Organic
The File::open("grocery-list", "w") do |f|
f << <<GROCERY_LIST
Grocery list
----
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*
* Organic
GROCERY_LIST
end
As with Unix shells, Ruby also allows for the delimiting identifier not to start on the first column of a line, if the start of the here document is marked with the slightly different starter now = Time.now
puts <<-EOF
It's #{now.hour} o'clock John, where are your kids?
EOF
Ruby expands on this by providing the "<<~" syntax for omitting indentation on the here document: puts <<~EOF
This line is indented two spaces.
This line is indented four spaces.
This line is indented six spaces.
EOF
The common indentation of two spaces is omitted from all lines: $ ruby indented-heredoc.rb
This line is indented two spaces.
This line is indented four spaces.
This line is indented six spaces.
Like Perl, Ruby allows for starting multiple here documents in one line: puts <<BEGIN + "<--- middle --->\n" + <<END
This is the beginning:
BEGIN
And now it is over!
END
# this equals this expression:
puts "This is the beginning:\n<--- middle --->\nAnd now it is over!"
As with Perl, Ruby features file literals, namely the contents of the file following PythonPython supports multi-line strings as a "verbatim" string. They may be enclosed in 3 single (') or double (") quotation marks, the latter is shown in the examples below. print("""
Customer: Not much of a cheese shop is it?
Shopkeeper: Finest in the district , sir.
""")
From Python 3.6 onwards, verbatim f-strings support variable and expression interpolation. shop_type = "CHEESE"
accolade = "finest"
print(f"""
Customer: Not much of a {shop_type.lower()} shop is it?
Shopkeeper: {accolade.capitalize()} in the district , sir.
""")
JavaText blocks are supported starting with Java 15 via JEP 378:[12][13] String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
C++Since C++11, C++ supports string literals with custom delimiter ("my_delimiter" in this example): #include <ostream>
const char* str = R"my_delimiter(Start of string. New line
slash \ quote " ' parens ) ( End of string)my_delimiter";
std::cout << str << std::endl;
will print out Start of string. New line slash \ quote " ' parens ) ( End of string DSince version 2.0, D has support for here document-style strings using the 'q' prefix character. These strings begin with int main() {
string list = q"IDENT
1. Item One
2. Item Two
3. Item Three
IDENT";
writef( list );
}
D also supports a few quoting delimiters, with similar syntax, with such strings starting with OS/JCLOn IBM's Job Control Language (JCL) used on its earlier MVS and current z/OS operating systems, data which is inline to a job stream can be identified by an * on a DD statement, such as
//AHAR JOB ('ALEX HARRIS')
// EXEC ASMLG
//SYSIN DD *
APROG START
XR 15,15
BR 14
END
/*
//* JOB ENDS
The RacketRacket's here strings start with #lang racket
(displayln
#<<HERESTRING
This is a simple here string in Racket.
* One
* Two
* Three
HERESTRING
)
Outputs: This is a simple here string in Racket.
* One
* Two
* Three
No escape sequences are recognized between the starting and terminating lines; all characters are included in the string (and terminator) literally. #lang racket
(displayln
#<<A here string in Racket ☺
This string spans for multiple lines
and can contain any Unicode symbol.
So things like λ, ☠, α, β, are all fine.
In the next line comes the terminator. It can contain any Unicode symbol as well, even spaces and smileys!
A here string in Racket ☺
)
Outputs: This string spans for multiple lines
and can contain any Unicode symbol.
So things like λ, ☠, α, β, are all fine.
In the next line comes the terminator. It can contain any Unicode symbol as well, even spaces and smileys!
Here strings can be used normally in contexts where normal strings would: #lang racket
(printf #<<END
Dear ~a,
Thanks for the insightful conversation ~a.
~a
END
"Isaac"
"yesterday"
"Carl")
Outputs: Dear Isaac,
Thanks for the insightful conversation yesterday.
Carl
An interesting alternative is to use the language extension
Outputs: This is a long string,
very convenient when a
long chunk of text is
needed.
No worries about escaping
"quotes" or \escapes. It's
also okay to have λ, γ, θ, ...
Embed code: 7
An @-expression is not specific nor restricted to strings, it is a syntax form that can be composed with the rest of the language. Windows PowerShellIn PowerShell, here documents are referred to as here-strings. A here-string is a string which starts with an open delimiter ( In the following PowerShell code, text is passed to a function using a here-string.
The function PS > function ConvertTo-UpperCase($string) { $string.ToUpper() }
PS > ConvertTo-UpperCase @'
>> one two three
>> eins zwei drei
>> '@
ONE TWO THREE
EINS ZWEI DREI
Here is an example that demonstrates variable interpolation and statement execution using a here-string with double quotes: PS > $doc, $marty = 'Dr. Emmett Brown', 'Marty McFly'
PS > $time = [DateTime]'Friday, October 25, 1985 8:00:00 AM'
PS > $diff = New-TimeSpan -Minutes 25
PS > @"
>> $doc : Are those my clocks I hear?
>> $marty : Yeah! Uh, it's $($time.Hour) o'clock!
>> $doc : Perfect! My experiment worked! They're all exactly $($diff.Minutes) minutes slow.
>> $marty : Wait a minute. Wait a minute. Doc... Are you telling me that it's $(($time + $diff).ToShortTimeString())?
>> $doc : Precisely.
>> $marty : Damn! I'm late for school!
>> "@
Dr. Emmett Brown : Are those my clocks I hear?
Marty McFly : Yeah! Uh, it's 8 o'clock!
Dr. Emmett Brown : Perfect! My experiment worked! They're all exactly 25 minutes slow.
Marty McFly : Wait a minute. Wait a minute. Doc... Are you telling me that it's 08:25?
Dr. Emmett Brown : Precisely.
Marty McFly : Damn! I'm late for school!
Using a here-string with single quotes instead, the output would look like this: PS > @'
>> $doc : Are those my clocks I hear?
>> $marty : Yeah! Uh, it's $($time.Hour) o'clock!
>> $doc : Perfect! My experiment worked! They're all exactly $($diff.Minutes) minutes slow.
>> $marty : Wait a minute. Wait a minute. Doc... Are you telling me that it's $(($time + $diff).ToShortTimeString())?
>> $doc : Precisely.
>> $marty : Damn! I'm late for school!
>> '@
$doc : Are those my clocks I hear?
$marty : Yeah! Uh, it's $($time.Hour) o'clock!
$doc : Perfect! My experiment worked! They're all exactly $($diff.Minutes) minutes slow.
$marty : Wait a minute. Wait a minute. Doc... Are you telling me that it's $(($time + $diff).ToShortTimeString())?
$doc : Precisely.
$marty : Damn! I'm late for school!
DIGITAL Command Language (DCL)In DCL scripts, any input line which does not begin with a $ symbol is implicitly treated as input to the preceding command - all lines which do not begin with $ are here-documents. The input is either passed to the program, or can be explicitly referenced by the logical name SYS$INPUT (analogous to the Unix concept of stdin). For instance, explicitly referencing the input as SYS$INPUT: $ TYPE SYS$INPUT
This text will be directly echoed
to the screen by the TYPE command.
$! other commands ...
produces: This text will be directly echoed
to the screen by the TYPE command.
Additionally, the DECK command, initially intended for punched card support (hence its name: it signified the beginning of a data deck) can be used to supply input to the preceding command.[16] The input deck is ended either by the command $ EOD, or the character pattern specified by the /DOLLARS parameter to DECK. Example of a program totalling up monetary values: $ RUN ADD_SUMS.EXE
$ DECK
$13.53
$3.33
$2.33
$ EOD
Would produce the following output (presuming ADD_SUMS was written to read the values and add them): $19.19
Example of using DECK /DOLLARS to create one command file from another: $ COPY SYS$INPUT SYS$SCRATCH:TEMP.COM
$ DECK /DOLLARS=$$$$
$ TYPE SYS$INPUT
This is an example of using DECK to create
a command file from within a command file
$$$$
$! other commands follow ...
YAMLYAML primarily relies on whitespace indentation for structure, making it resistant to delimiter collision and capable representing multi-line strings with folded string literals: ---
caption: "Example of heredoc-style functionality using YAML"
date: "2007-06-01"
example: >
HTML goes into YAML without modification
message: |
<blockquote style="font: italic 12pt Times">
<p>"Three is always greater than two,
even for large values of two"</p>
<p>--Author Unknown</p>
</blockquote>
See alsoReferences
Notes
General
External links
|