Unwanted Line Break Using Echo and Cat

Unwanted empty lines using echo and cat

Perhaps your original file has MS-DOS line endings (\r\n), and whatever you use to display the file is smart enough to detect that. Then, when you add a line with unix line ending (\n) to the top, the detection breaks, and you get shown the blank lines inbetween.

Edit
There are myriads of ways to convert line endings. Most editors can do it for you interactively. In your case, you can for instance extend your pipeline with

| tr -d '\r' > output.txt

In bash got unwanted newlines after sed and cat

The issue is that your sed command, instead of deleting the line of interest, turns it into an empty line, so in effect you blank out an old NAS entry while adding a new line for it, which keeps adding lines.

Use the following sed command instead, which deletes the matching line:

sr="/${nas_name}/ d"

or, more robustly, to rule out false positives:

sr="/[[:blank:]]${nas_name}[[:blank:]]*$/ d"

Since a double-quoted string is used, you generally have to use \$ for $ chars. that the shell should not expand.

However, the shell leaves something that is not a syntactically valid variable reference alone, so $/ is passed through to sed as-is.

For stricter separation of the shell expanded part (double-quoted) and the Sed script (single-quoted), you can use the following, which, however, is harder to read: sr='/[[:blank:]]'"${nas_name}"'[[:blank:]]*$/ d'. Generally, though, it's a worthwhile approach.

Note that your script could be simplified in many ways, including using a single sed command to update the existing entry directly instead of deleting the old entry with sed first and then appending a new one with cat.

All newlines are removed when saving cat output into a variable

The shell is splitting the msgs variable so echo get multiple parameters.
You need to quote your variable to prevent this to happen:

echo "$msgs"

How to preserve line breaks when storing command output to a variable?

Quote your variables. Here is it why:

$ f="fafafda
> adffd
> adfadf
> adfafd
> afd"


$ echo $f
fafafda adffd adfadf adfafd afd


$ echo "$f"
fafafda
adffd
adfadf
adfafd
afd

Without quotes, the shell replaces $TEMP with the characters it contains (one of which is a newline). Then, before invoking echo shell splits that string into multiple arguments using the Internal Field Separator (IFS), and passes that resulting list of arguments to echo. By default, the IFS is set to whitespace (spaces, tabs, and newlines), so the shell chops your $TEMP string into arguments and it never gets to see the newline, because the shell considers it a separator, just like a space.

Why does only one output of the 'cat' command come with a linebreak?

The rsyslogd.pid file probably doesn't end with a newline character (ASCII 0x0A).

You didn't mention how you opened the files, but, I suspect you used a text editor which will not display non-printable characters (like newline and backspace). Rather than using a text editor try looking at the raw file with the hexdump tool. Then compare the hex values against an ASCII table. I think you will find that the non-printable characters after the 599 and 636 are different.

hexdump -C rsyslogd.pid
hexdump -C acpid.pid

The following sequence of commands reproduces your output. The key is to use the -n flag for the echo command to create a file without a newline character at the end.

$ echo -n test > file_no_new_line.txt
$ echo test > file_with_new_line.txt
$ cat file_no_new_line.txt
test$ cat file_with_new_line.txt
test
$

Here is the output of hexdump for the two files shown in my example.

$ hexdump -C file_no_new_line.txt
00000000 74 65 73 74 |test|
00000004
$ hexdump -C file_with_new_line.txt
00000000 74 65 73 74 0a |test.|
00000005
$

The command output, in this case from cat, and the shell prompt ($) running into each other is also shell dependent. If the behavior can't be reproduce with the steps above try another shell (e.g. /bin/sh)

No line breaks with cat

You could try:

echo $chksitename | tr ' ' '\n'

Bash: Strip trailing linebreak from output

If your expected output is a single line, you can simply remove all newline characters from the output. It would not be uncommon to pipe to the tr utility, or to Perl if preferred:

wc -l < log.txt | tr -d '\n'

wc -l < log.txt | perl -pe 'chomp'

You can also use command substitution to remove the trailing newline:

echo -n "$(wc -l < log.txt)"

printf "%s" "$(wc -l < log.txt)"

If your expected output may contain multiple lines, you have another decision to make:

If you want to remove MULTIPLE newline characters from the end of the file, again use cmd substitution:

printf "%s" "$(< log.txt)"

If you want to strictly remove THE LAST newline character from a file, use Perl:

perl -pe 'chomp if eof' log.txt

Note that if you are certain you have a trailing newline character you want to remove, you can use head from GNU coreutils to select everything except the last byte. This should be quite quick:

head -c -1 log.txt

Also, for completeness, you can quickly check where your newline (or other special) characters are in your file using cat and the 'show-all' flag -A. The dollar sign character will indicate the end of each line:

cat -A log.txt

Bash: redirect `cat` to file without newline

With these inputs:

userInput="Test Test Test"

echo "Line 1
Line 2
Line 3" >file1

echo "Line 4
Line 5
Line 6" >file2

I would do:

printf "%s%s%s" "$(cat file1)" "$userInput" "$(cat file2)" >newfile

The creation of >newfile is equivalent to touch and adding content in your first step. A bit easier to see intent with this.

I get:

$ cat newfile
Line 1
Line 2
Line 3Test Test TestLine 4
Line 5
Line 6

How to remove a newline from a string in Bash

Under bash, there are some bashisms:

The tr command could be replaced by // bashism:

COMMAND=$'\nREBOOT\r   \n'
echo "|${COMMAND}|"
|
OOT
|

echo "|${COMMAND//[$'\t\r\n']}|"
|REBOOT |

echo "|${COMMAND//[$'\t\r\n ']}|"
|REBOOT|

See Parameter Expansion and QUOTING in bash's man page:

man -Pless\ +/\/pattern bash
man -Pless\ +/\\\'string\\\' bash

man -Pless\ +/^\\\ *Parameter\\\ Exp bash
man -Pless\ +/^\\\ *QUOTING bash

Further...

As asked by @AlexJordan, this will suppress all specified characters. So what if $COMMAND do contain spaces...

COMMAND=$'         \n        RE BOOT      \r           \n'
echo "|$COMMAND|"
|
BOOT
|

CLEANED=${COMMAND//[$'\t\r\n']}
echo "|$CLEANED|"
| RE BOOT |

shopt -q extglob || { echo "Set shell option 'extglob' on.";shopt -s extglob;}

CLEANED=${CLEANED%%*( )}
echo "|$CLEANED|"
| RE BOOT|

CLEANED=${CLEANED##*( )}
echo "|$CLEANED|"
|RE BOOT|

Shortly:

COMMAND=$'         \n        RE BOOT      \r           \n'
CLEANED=${COMMAND//[$'\t\r\n']} && CLEANED=${CLEANED%%*( )}
echo "|${CLEANED##*( )}|"
|RE BOOT|

Note: bash have extglob option to be enabled (shopt -s extglob) in order to use *(...) syntax.



Related Topics



Leave a reply



Submit