15

How can I enter the following contents in a file:

Hi
abcd

I tried using echo "Hi\nabcd" >> ab.txt, but in the file it's written as is (the \n is included, instead of a newline)

Novice User
  • 1,349
  • 1
    agreed (the suggested link is adequate) – Thomas Dickey Nov 25 '15 at 12:45
  • @DmitryGrigoryev But the question was closed, since it was to broad. So what do you want a to broad question or a question to the point? I think the answer should be here and not on the closed question. – Raphael Ahrens Nov 25 '15 at 13:44
  • @RaphaelAhrens That question got answered nevertheless, and the first answer covers most (if not all) of the information here. What is the benefit of having those answers the second time? – Dmitry Grigoryev Nov 25 '15 at 13:52
  • Question was closed as a duplicate of another question that was itself already closed as being too vague. That should not have happened. – psusi Feb 24 '22 at 20:08

6 Answers6

18

You need to tell echo to honor escape sequences.

echo -e "Hi\nabcd" >> ab.txt
15

The behavior of echo varies from shell to shell¹; printf's behavior is more standard.

printf "Hi\nabcd" >> ab.txt

¹ "It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted."

ephemient
  • 15,880
  • 1
    Best answer, IMO. – jw013 Apr 02 '12 at 17:56
  • Yup. I've been bitten when echo's behavior changed in a system update, and some of my scripts broke... – Gordon Davisson Apr 02 '12 at 22:59
  • type printf printf is a shell builtin - it's the same situation as with echo: in bash it is a builtin. – user unknown Apr 03 '12 at 13:51
  • @userunknown: You may be missing the point. printf "foo\nbar\n" will work on every system, shell builtin or not, while echo -e "foo\nbar" definitely won't. – peth Apr 04 '12 at 14:35
  • @user112553: My point is, that a builtin might be implemented differently, but I don't know every shell, so maybe all behave the same for println, but not for echo. – user unknown Apr 04 '12 at 14:40
  • @userunknown: I understand where you're coming from. printf behavior is defined in the POSIX standard; a shell would lose compliance if it implemented an overriding incompatible builtin. The -e switch to echo, though, isn't. – peth Apr 04 '12 at 14:52
10

I would suggest using bash shell feature called Here Document. Seems like the most elegant form to achieve what you describe. Most importantly the multiline content looks exactly same way as you would have it in the output file (as opposed to unreadable, long, \n separated strings).

cat > ab.txt <<EOL
Hi
abcd
EOL

The EOL here is the marker that tells what shell should look for to find the end of the here document. You can arbitrarily pick a word which let's you choose something that will not coincidentally conflict with the here document's contents itself. Nice thing is you could have shell ${VARIABLES} which will be substituted. If that's somehow unwanted, you can always wrap the opening (only the opening one!) marker word with quotes (') to prevent it.

I personally use this a lot in the init scripts to create small config files when setting my environment, something like:

cat > ~/.screenrc <<END_OF_HEREDOC_MARKER
defscrollback ${MAX_LINES}
END_OF_HEREDOC_MARKER
msciwoj
  • 371
  • Note: you can not sudo the above command so if you don't have write permission in that position that won't work. – kroiz Feb 16 '16 at 11:42
7

You can also just do cat > file, then type away and hit Ctrl-D when you're done.

psusi
  • 17,303
5

You can also play games with quoting:

 % echo 'Hi
> abcd' >> ab.txt

You type that in bash by hitting "Enter" after "Hi". Bash uses '>' as its continuation-of-command prompt for me. I could not escape an individual return with a backslash for some reason.

0
cp /dev/tty file

press enter. then start typing. continue typing as much as you'd like. when you have had your fill of all of the typing, enter your tty EOF string. this is usually sent with CTRL+D. now maybe press it once more. you're done.

mikeserv
  • 58,310