ChatGPT解决这个技术问题 Extra ChatGPT

Echo newline in Bash prints literal \n

How do I print a newline? This merely prints \n:

$ echo -e "Hello,\nWorld!"
Hello,\nWorld!
For those saying "it works for me", the behavior of echo varies quite a bit between versions. Some will even print the "-e" as part of their output. If you want predictable behavior for anything nontrivial, use printf instead (as in @sth's answer).
I could not get any of the suggestions in this answer working, because, as it turns out, I was attempting to use it in a function that returns a value, and all the echo (and printf) messages in the function were being appended to the return value after being individually stripped of newlines. Here is a question regarding this, with an extremely thorough answer: stackoverflow.com/questions/27872069/… This was like a three hour mystery tour.
Also notable: in Unix & Linux Stack Exchange, the accepted answer to How to add new lines when using echo
echo -ne "hello\nworld" (you needed the n flag to interpret escapes) - but as others say, different echo commands may have different results!
@Konchog echo -n man page entry on archlinux ` -n do not output the trailing newline` It has nothing to do with interpreting escapes

M
Mateen Ulhaq

Use printf instead:

printf "hello\nworld\n"

printf behaves more consistently across different environments than echo.


or even printf %"s\n" hello world -- printf will reuse the format if too many arguments are given
The OP asked about echo, not printf; and @choroba's answer below, which uses the -e option, fills the bill perfectly.
@JESii: It fits if your echo happens to support the -e option.
With some versions of echo, -e is just printed in the output itself so I think this answer is perfectly valid since echo isn't consistent here (unless we're talking about a specific version).
This is well and good if printf is available, but unlike echo sometimes printf isn't on the distro.
c
choroba

Make sure you are in Bash.

$ echo $0
bash

All these four ways work for me:

echo -e "Hello\nworld"
echo -e 'Hello\nworld'
echo Hello$'\n'world
echo Hello ; echo world

-e flag did it for me, which "enables interpretation of backslash escapes"
I think -e param doesn't exist on all *nix OS
@kenorb: It exists in bash. It is a builtin.
Why does the third one work? Without the $ it returns "Hello n world"
As mentioned by various other -e does NOT work for all distributions and versions. In some cases it is ignored and in others it will actually be printed out. I don't believe this fixed it for the OP so should not be accepted answer
R
Rory O'Kane
echo $'hello\nworld'

prints

hello
world

$'' strings use ANSI C Quoting:

Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard.


@EvgeniSergeev Not sure what you mean, but it didn't work for me either first. And that's because I was using double quotes and turns out this works only with single quotes! Tried in Terminal on Mac.
Problems with variables in the string not being expanded.
You can still concatenate double-quote strings. ` foo="bar"; echo $''$foo'efoot'`
This is what I wanted. Works fine on Xenial.
It woks on GNU bash, version 4.4.23(1)-release (x86_64-pc-msys) W10 like a charm.
P
Peter Mortensen

You could always do echo "".

For example,

echo "Hello,"
echo ""
echo "World!"

echo "" works for me and I think it's the simplest form to print a new line, even if this doesn't directly answer the question. Cheers.
I think it's less obvious (and thus potentially more confusing) than echo -en "\n".
echo is enough to obtain an empty line
The \n did not work when you are using the read. But your method worked for adding a line.
i had trouble getting the other answers to work on Mac. i ended up going with this incredibly obvious solution. :)
P
Peter Mortensen

On the off chance that someone finds themselves beating their head against the wall trying to figure out why a coworker's script won't print newlines, look out for this:

#!/bin/bash
function GET_RECORDS()
{
   echo -e "starting\n the process";
}

echo $(GET_RECORDS);

As in the above, the actual running of the method may itself be wrapped in an echo which supersedes any echos that may be in the method itself. Obviously, I watered this down for brevity. It was not so easy to spot!

You can then inform your comrades that a better way to execute functions would be like so:

#!/bin/bash
function GET_RECORDS()
{
   echo -e "starting\n the process";
}

GET_RECORDS;

Be sure you wrap the variable with quotes before echoing it out of the method.
v
vinzee

Simply type

echo

to get a new line


Vastly underrated answer, can't believe this question has amassed 20+ answers since 2011 and that not one of them contains this simple solution.
alias c='echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ; echo ;' This is the only way I can clear my screen, thanks!
@Ahi Tuna: Please use your console keyboard shortcuts instead :)
On the screen-clearing, Ctrl+L will also clear the screen on the majority of terminals.
@AhiTuna to clear screen, just type clear command
C
Ciro Santilli Путлер Капут 六四事

POSIX 7 on echo

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html

-e is not defined and backslashes are implementation defined:

If the first operand is -n, or if any of the operands contain a character, the results are implementation-defined.

unless you have an optional XSI extension.

So I recommend that you should use printf instead, which is well specified:

format operand shall be used as the format string described in XBD File Format Notation [...]

the File Format Notation:

\n Move the printing position to the start of the next line.

Also keep in mind that Ubuntu 15.10 and most distros implement echo both as:

a Bash built-in: help echo

a standalone executable: which echo

which can lead to some confusion.


a
alinsoar
str='hello\nworld'
$ echo | sed "i$str"
hello
world

This is actually a great answer since it works for string concatenations. Great!
Why bother to invoke a second program? It's not that we are trying to write a real time application in bash ;) but its not necessary.
P
Peter Mortensen

You can also do:

echo "hello
world"

This works both inside a script and from the command line.

On the command line, press Shift+Enter to do the line break inside the string.

This works for me on my macOS and my Ubuntu 18.04 (Bionic Beaver) system.


P
Peter Mortensen

There is a new parameter expansion added in Bash 4.4 that interprets escape sequences:

${parameter@operator} - E operator The expansion is a string that is the value of parameter with backslash escape sequences expanded as with the $'…' quoting mechanism.

$ foo='hello\nworld'
$ echo "${foo@E}"
hello
world

worked like a charm for printing a message that was a variable inside a function, from outside the function.
P
Peter Mortensen

I just use echo without any arguments:

echo "Hello"
echo
echo "World"

This is wrong as Hello is followed by two line breaks and not only one.
A
Anish

To print a new line with echo, use:

echo

or

echo -e '\n'

Try just 'echo'
D
Dhwanit

This could better be done as

x="\n"
echo -ne $x

-e option will interpret backslahes for the escape sequence -n option will remove the trailing newline in the output

PS: the command echo has an effect of always including a trailing newline in the output so -n is required to turn that thing off (and make it less confusing)


echo -ne "hello\nworld" for the exact answer of the question :)
s
skiggety

If you're writing scripts and will be echoing newlines as part of other messages several times, a nice cross-platform solution is to put a literal newline in a variable like so:

newline='
'

echo "first line$newlinesecond line"
echo "Error: example error message n${newline}${usage}" >&2 #requires usage to be defined

P
Peter Mortensen

My script:

echo "WARNINGS: $warningsFound WARNINGS FOUND:\n$warningStrings

Output:

WARNING : 2 WARNINGS FOUND:\nWarning, found the following local orphaned signature file:

On my Bash script I was getting mad as you until I've just tried:

echo "WARNING : $warningsFound WARNINGS FOUND:
$warningStrings"

Just hit Enter where you want to insert that jump. The output now is:

WARNING : 2 WARNINGS FOUND:
Warning, found the following local orphaned signature file:

Just a note, you will probably want to use ${ } around your variable names as not doing so can lead to really weird behavior when a shell finds a variable called $warningsFound and prints that and not the two separate outputs.
@dragon788 maybe I'm missing something, but the variable IS actually called $warningsFound ?
I missed a word on that. If you had a variable called $warnings, in some cases without using ${warningsFound}, you could potentially end up with the contents of $warnings + "Found" instead of the variable you intended.
P
Peter Mortensen

If the previous answers don't work, and there is a need to get a return value from their function:

function foo()
{
    local v="Dimi";
    local s="";
    .....
    s+="Some message here $v $1\n"
    .....
    echo $s
}

r=$(foo "my message");
echo -e $r;

Only this trick worked on a Linux system I was working on with this Bash version:

GNU bash, version 2.2.25(1)-release (x86_64-redhat-linux-gnu)

G
Gary Tessman

For only the question asked (not special characters etc) changing only double quotes to single quotes.

echo -e 'Hello,\nWorld!'

Results in:

Hello,
World!

A
Avinash Raj

You could also use echo with braces,

$ (echo hello; echo world)
hello
world

syntax error near unexpected token `(' when called in .sh file
try echo hello; echo world
Or "echo hello && echo world" or just:" echo hello echo world
An explanation would be in order.
J
Joe Healy

This got me there....

outstuff=RESOURCE_GROUP=[$RESOURCE_GROUP]\\nAKS_CLUSTER_NAME=[$AKS_CLUSTER_NAME]\\nREGION_NAME=[$REGION_NAME]\\nVERSION=[$VERSION]\\nSUBNET-ID=[$SUBNET_ID]
printf $outstuff

Yields:

RESOURCE_GROUP=[akswork-rg]
AKS_CLUSTER_NAME=[aksworkshop-804]
REGION_NAME=[eastus]
VERSION=[1.16.7]
SUBNET-ID=[/subscriptions/{subidhere}/resourceGroups/makeakswork-rg/providers/Microsoft.Network/virtualNetworks/aks-vnet/subnets/aks-subnet]

An explanation would be in order. E.g, what is the gist/idea? Please respond by editing your answer, not here in comments (without "Edit:", "Update:", or similar - the answer should appear as if it was written today).
This is a good use when you can't add quotes!
H
Hunter Frazier

Sometimes you can pass multiple strings separated by a space and it will be interpreted as \n.

For example when using a shell script for multi-line notifcations:

#!/bin/bash
notify-send 'notification success' 'another line' 'time now '`date +"%s"`

This is incorrect. It is never interpreted as \n. It is interpreted as a separate argument to the program, and the program itself may display that argument on a new line, but that doesn't mean that it was converted to \n at any point and is entirely dependent on the program.
J
JanB

With jq:

$ jq -nr '"Hello,\nWorld"'
Hello,
World

P
Peter Mortensen

Additional solution:

In cases, you have to echo a multiline of the long contents (such as code/ configurations)

For example:

A Bash script to generate codes/ configurations

echo -e, printf might have some limitation

You can use some special char as a placeholder as a line break (such as ~) and replace it after the file was created using tr:

echo ${content} | tr '~' '\n' > $targetFile

It needs to invoke another program (tr) which should be fine, IMO.


This is a poor solution. There is absolutely no need to invoke tr in this case. Furthermore, what if the text includes a ~ already?