How can I stop a here string (<<<) from adding a line break or new lines?
Asked Answered
I

3

26

It seems that here string is adding line break. Is there a convenient way of removing it?

$ string='test'
$ echo -n $string | md5sum
098f6bcd4621d373cade4e832627b4f6  -
$ echo $string | md5sum
d8e8fca2dc0f896fd7cb4cb0031ba249  -
$ md5sum <<<"$string"
d8e8fca2dc0f896fd7cb4cb0031ba249  -
Insurer answered 9/6, 2016 at 14:24 Comment(1)
<<< also adds trailing newlinesLitman
P
26

Yes, you are right: <<< adds a trailing new line.

You can see it with:

$ cat - <<< "hello" | od -c
0000000   h   e   l   l   o  \n
0000006

Let's compare this with the other approaches:

$ echo "hello" | od -c
0000000   h   e   l   l   o  \n
0000006
$ echo -n "hello" | od -c
0000000   h   e   l   l   o
0000005
$ printf "hello" | od -c
0000000   h   e   l   l   o
0000005

So we have the table:

         | adds new line |
-------------------------|
printf   |      No       |
echo -n  |      No       |
echo     |      Yes      |
<<<      |      Yes      |

From Why does a bash here-string add a trailing newline char?:

Most commands expect text input. In the unix world, a text file consists of a sequence of lines, each ending in a newline. So in most cases a final newline is required. An especially common case is to grab the output of a command with a command susbtitution, process it in some way, then pass it to another command. The command substitution strips final newlines; <<< puts one back.

Playoff answered 9/6, 2016 at 14:35 Comment(1)
Also, note that a here-string is a shortcut for a single-line here document, which always ends with a newline.Mignon
D
7

fedorqui's helpful answer shows that and why here-strings (and also here-documents) invariably append a newline.

As for:

Is there a convenient way of removing it?

In Bash, use printf inside a process substitution as an "\n-less" alternative to a here-string:

... < <(printf %s ...)

Applied to your example:

$ md5sum < <(printf %s 'test')
098f6bcd4621d373cade4e832627b4f6

Alternatively, as user202729 suggests, simply use printf %s in the pipeline, which has the added advantage of not only using a more familiar feature but also making the command work in (more strictly) POSIX-compliant shells (in scripts targeting /bin/sh):

$ printf %s 'test' | md5sum
098f6bcd4621d373cade4e832627b4f6
Donald answered 10/6, 2016 at 23:7 Comment(0)
B
2

As a "here doc" add a newline:

$ string="hello test"
$ cat <<_test_ | xxd
> $string
> _test_
0000000: 6865 6c6c 6f20 7465 7374 0a              hello test.

Also a "here string" does:

$ cat <<<"$string" | xxd
0000000: 6865 6c6c 6f20 7465 7374 0a              hello test.

Probably the easiest solution to get an string non-ending on newline would be printf:

$ printf '%s' "$string" | xxd
0000000: 6865 6c6c 6f20 7465 7374                 hello test
Beardsley answered 10/6, 2016 at 22:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.