How to prevent grep from printing a trailing newline?
You can pipe it through tr
and translate the \n
to a \0
character:
tr '\n' '\0'
prevent newline in cut command
There are many ways. In addition to isedev and fedorqui's answers, you could also do:
perl -ne '/^([^.]+)/ && print $1' <<< "test.test"
cut -d. -f1 <<< "test.test" | tr -d $'\n'
cut -d. -f1 <<< "test.test" | perl -pe 's/\n//'
while read -d. i; do printf "%s" "$i"; done <<< "test.test
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
How can I 'echo' out things without a newline?
Yes. Use the -n
option:
echo -n "$x"
From help echo
:
-n do not append a newline
This would strips off the last newline too, so if you want you can add a final newline after the loop:
for ...; do ...; done; echo
Note:
This is not portable among various implementations of echo
builtin/external executable. The portable way would be to use printf
instead:
printf '%s' "$x"
How to avoid bash command substitution to remove the newline character?
Non-trailing newlines are not removed
The newlines you are looking for are there, you just don't see them, because you use echo
without quoting the variable.
Validation:
$ a=$( df -H )
$ echo $a
Filesystem Size Used Avail Use% Mounted on /dev/sda3 276G 50G 213G 19% / udev 2.1G 4.1k 2.1G 1% /dev tmpfs 832M 820k 832M 1% /run none 5.3M 0 5.3M 0% /run/lock none 2.1G 320k 2.1G 1% /run/shm
$ echo "$a"
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 276G 50G 213G 19% /
udev 2.1G 4.1k 2.1G 1% /dev
tmpfs 832M 820k 832M 1% /run
none 5.3M 0 5.3M 0% /run/lock
none 2.1G 320k 2.1G 1% /run/shm
$
Trailing newlines are removed
As @user4815162342 correctly pointed out, although newlines within the output are not removed, trailing newlines are removed with command substitution. See experiment below:
$ a=$'test\n\n'
$ echo "$a"
test
$ b=$(echo "$a")
$ echo "$b"
test
$
In most cases this does not matter, because echo
will add the removed newline (unless it is invoked with the -n
option), but there are some edge cases where there are more that one trailing newlines in the output of a program, and they are significant for some reason.
Workarounds
1. Add dummy character
In these case, as @Scrutinizer mentioned, you can use the following workaround:
$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test
$
Explanation: Character x
is added to the output (using printf x
), after the newlines. Since the newlines are not trailing any more, they are not removed by the command substitution. The next step is to remove the x
we added, using the %
operator in ${a%x}
. Now we have the original output, with all newlines present!!!
2. Read using process substitution
Instead of using command substitution to assign the output of a program to variable, we can instead use process substitution to feed the output of the program to the read
built-in command (credit to @ormaaj). Process substitution preserves all newlines. Reading the output to a variable is a bit tricky, but you can do it like this:
$ IFS= read -rd '' var < <( printf 'test\n\n' )
$ echo "$var"
test
$
Explanation:
- We set the internal field separator for the read command to null, with
IFS=
. Otherwiseread
would not assign the entire output tovar
, but only the first token. - We invoke
read
with options-rd ''
. Ther
is for preventing the backslash to act as a special character, and withd ''
set the delimiter to nothing, so that read reads the entire output, instead of just the first line.
3. Read from a pipe
Instead of using command or process substitution to assign the output of a program to variable, we can instead pipe the output of the program to the read
command (credit to @ormaaj). Piping also preserves all newlines. Note however, that this time we set the lastpipe
shell optional behavior, using the shopt
builtin. This is required, so that the read
command is executed in the current shell environment. Otherwise, the variable will be assigned in a subshell, and it will not be accessible from the rest of the script.
$ cat test.sh
#!/bin/bash
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh
test
$
Remove blank lines with grep
Try the following:
grep -v -e '^$' foo.txt
The -e
option allows regex patterns for matching.
The single quotes around ^$
makes it work for Cshell. Other shells will be happy with either single or double quotes.
UPDATE: This works for me for a file with blank lines or "all white space" (such as windows lines with \r\n
style line endings), whereas the above only removes files with blank lines and unix style line endings:
grep -v -e '^[[:space:]]*$' foo.txt
printing grep -o output in single line
You could do it all with this sed instruction
echo "Hello Guys!" |sed 's/[^A-Z]//g'
UPDATE
Breakdown of sed command:
The s/// is sed's substitute command. It simply replaces the first RegEx (the one between the first and the second slash) with the Expression between slash two and three. The trailing g stands for global, i.e, do this for every match of the RegEx in the current line. Without the g it would just stop processing after the first match. The RegEx itself is matching any non-capital letter and then those letters are replaced with nothing, i.e., effectively deleted.
Related Topics
Check Whether a Certain File Type/Extension Exists in Directory
Linux: Which Process Is Causing "Device Busy" When Doing Umount
In Linux, What Do All the Values in the "Top" Command Mean
How to Skip Saturday and Sunday in a Cron Expression
How to Set the Grep After Context to Be "Until the Next Blank Line"
Linux: Set Permission Only to Directories
How to Make Vim Play Typewriter Sound When I Write a Letter
Installed Clang++3.6 on Ubuntu, Can't Select as Alternative
Get Current Time in Hours and Minutes
Getting Stacktrace from Core Dump
In Screen, How to Send a Command to All Virtual Terminal Windows Within a Single Screen Session
How to Pass Argument in Expect Through the Command Line in a Shell Script
How to Count Number of Unique Values of a Field in a Tab-Delimited Text File
How to Speed Up Linux Kernel Compilation
Listing All User-Installed Packages in Debian
How to Find Which Yocto Project Recipe Populates a Particular File on an Image Root Filesystem
Open Vim from Within a Bash Shell Script
Centos/Linux Setting Logrotate to Maximum File Size for All Logs