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
Libpcap - Capture Packets from All Interfaces
How to Add Boost Library to Code::Blocks in Linux
Are Pid-Files Still Flawed When Doing It 'Right'
Shell Script for Process Monitoring
Find Value from One CSV in Another One (Like Vlookup) in Bash (Linux)
Capturing Display/Monitor Images, Sending Keyboard Input on Linux
Clear Screen in a Linux Terminal Using Assembly
Linux How to Add a File to a Specific Folder Within a Zip File
Passing Environment Variables Not Working with Docker
How to Create a Zip File Without Entire Directory Structure
Sshpass: Command Not Found Error
Padding Empty Field in Unix Join Operation
How to Check If a File Contains Only Zeros in a Linux Shell
Combine Results of Column One Then Sum Column 2 to List Total for Each Entry in Column One
How to Acess the Physical Address from Linux Kernel Space
Difference Between Trap Flag (Tf) and Monitor Trap Flag
Send a Binary File (Line by Line) to a Socket Server with Netcat