Here document: Difference between revisions
→Python: It is a string literal used as a here doc. |
→External links: New section with link to Rosetta code task on here documents |
||
Line 390: | Line 390: | ||
*[[String literal]] |
*[[String literal]] |
||
*[[Docstring]] |
*[[Docstring]] |
||
==External links== |
|||
* [http://rosettacode.org/wiki/Here_document Here document]. Link to [[Rosetta code]] task with examples of here documents in over 15 languages. |
|||
==References== |
==References== |
Revision as of 11:22, 7 September 2011
A here document (also called a here-document, a heredoc, a hereis, a here-string or a here-script) is a way of specifying a string literal in command line shells including Unix shells (sh, csh, ksh, Bash and zsh) and in programming or scripting languages such as Perl, PHP, Python, PowerShell and Ruby. It preserves the line breaks and other whitespace (including indentation) in the text. Some languages allow variable substitution and command substitution inside the string.
The most common syntax for here documents is <<
followed by a delimiting identifier, followed, starting on the next line, by the text to be quoted, and then closed by the same identifier on its own line. Under the Unix shells, here documents are generally used as a way of providing input to commands.
Specific implementations
The following sections provide examples of specific implementations in different programming languages and environments. The most common syntax is substantially similar to that used by the Unix shell, but some tools provide similar functionality by means of different conventions, and under different names.
Command-line shells
Unix Shells
In the following example, text is passed to the tr
command using a here document.
$ tr a-z A-Z <<END_TEXT
> one two three
> uno dos tres
> END_TEXT
ONE TWO THREE
UNO DOS TRES
END_TEXT
was used as the delimiting identifier. It specified the start and end of the here document. ONE TWO THREE
and UNO DOS TRES
are outputs from tr
after execution.
Appending a minus sign to the << has the effect that leading tabs are ignored. This allows indenting here documents in shell scripts without changing their value. (Note that you will probably need to type CTRL-V, TAB to actually enter a TAB character on the command line. Tab emulated here with spaces; don't copy and paste.)
$ tr a-z A-Z <<-END_TEXT
> one two three
> uno dos tres
> END_TEXT
ONE TWO THREE
UNO DOS TRES
By default variables and also commands in backticks are evaluated:
$ cat << EOF
> Working dir $PWD
> EOF
Working dir /home/user
This can be disabled by quoting any part of the label. For example by setting it in single or double quotes:
$ cat << "EOF"
> Working dir $PWD
> EOF
Working dir $PWD
Also you can use a here-string in Bash:
$ tr a-z A-Z <<<"Yes it is a string"
YES IT IS A STRING
Windows PowerShell
In Windows PowerShell, here documents are referred to as here-strings. A here-string is a string which starts with an open delimiter (@"
or @'
) and ends with a close delimiter ("@
or '@
) on a line by itself, which terminates the string. All characters between the open and close delimiter are considered the string literal.
Using a here-string with double quotes allows variables to be interpreted, using single quotes doesn't.
Variable interpolation occurs with simple variables (e.g. $x
but NOT $x.y
or $x[0]
).
You can execute a set of statements by putting them in $()
(e.g. $($x.y)
or $(Get-Process | Out-String)
).
In the following PowerShell code, text is passed to a function using a here-string.
The function ConvertTo-UpperCase
is defined as follows:
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:
$doc, $marty = 'Dr. Emmett Brown', 'Marty McFly' $time = [DateTime]'Friday, October 25, 1985 8:00:00 AM' $diff = New-TimeSpan -Minutes 25 @" $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! "@
Output:
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:
$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!
Programming languages
D
Since version 2.0, D has support for delimiter strings using the 'q' prefix character. These strings begin and end with a delimiter character (any of () <> {} or []), or an identifier immediately followed by a newline.
The following D code shows 2 examples using delimiter characters and an identifier.
int main() {
string list = q"[1. Item One
2. Item Two
3. Item Three]";
writef( list );
}
Using an identifier.
int main() {
string list = q"IDENT
1. Item One
2. Item Two
3. Item Three
IDENT";
writef( list );
}
Perl
In Perl there are several different ways to invoke here docs.[1] Using the delimiter around the tag has the same effect on the here doc as the delimiter on a regular string literal: Using double quotes around the tag allows variables to be interpolated, using single quotes doesn't, and using the tag without either behaves like double quotes. Using backticks as the delimiter 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
PHP
In PHP, here documents are referred to as heredocs.
<?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 strtolower($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!
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 with the line number being at the end of the script.[2]
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[3]:
$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.
Python
Python supports string literals delimited by single or double quotes repeated three times (i.e. '''
or """
). These string literals can span multiple lines and support the functionality of here documents.
A simple Python 3 compatible example that yields the same result as the first Perl example above, is:
print """Dear {recipient},
I wish you to leave Sunnydale and never return.
Not Quite Love,
{sender}
""".format(sender='Buffy the Vampire Slayer', recipient='Spike')
Replace the call to the print
function with the keyword print
in Python versions older than 3.0. The Template
class described in PEP 292 (Simpler String Substitutions) provides similar functionality for variable interpolation and may be used in combination with the Python triple-quotes syntax.
Ruby
The 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
Writing to a file with a here document involves a profusion of chevron ('<'
) symbols:
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
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 "<<-". Besides, Ruby treats here documents as a double-quoted string, and as such, it is possible to use the #{} construct to interpolate code. The following example illustrates both of these features :
now = Time.now
puts <<-EOF
It's #{now.hour} o'clock John, where are your kids?
EOF
Ruby also 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!"
Tcl
Tcl has no special syntax for heredocs, because the ordinary string syntaxes already allow embedded newlines and preserve indentation. Brace-delimited strings have no substitution (interpolation):
puts {
Grocery list
------------
1. Salad mix.
2. Strawberries.*
3. Cereal.
4. Milk.*
* Organic
}
Quote-delimited strings are substituted at runtime:
set sender "Buffy the Vampire Slayer"
set recipient "Spike"
puts "
Dear $recipient,
I wish you to leave Sunnydale and never return.
Not Quite Love,
$sender
"
In brace-delimited strings, there is the restriction that they must be balanced with respect to unescaped braces. In quote-delimited strings, braces can be unbalanced but backslashes, dollar signs, and left brackets all trigger substitution, and the first unescaped double quote terminates the string.
A point to note is that both the above strings have a newline as first and last character, since that is what comes immediately after and before respectively the delimiters. string trim
can be used to remove these if they are unwanted:
puts [string trim "
Dear $recipient,
I wish you to leave Sunnydale and never return.
Not Quite Love,
$sender
" \n]
Similarly, string map
can be used to effectively set up variant syntaxes, e.g. undoing a certain indentation or introducing nonstandard escape sequences to achieve unbalanced braces.
See also
- tr (program) for information about tr(1)
- Pipeline (Unix) for information about pipes
- String literal
- Docstring
External links
- Here document. Link to Rosetta code task with examples of here documents in over 15 languages.