When I execute commands in Bash (or to be specific, wc -l < log.txt
), the output contains a linebreak after it. How do I get rid of it?
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
tr --delete '\n'
. –
Ento | tr -d '\r'
–
Clavate head -c ...
version -- Because I can now feed commands to the clipboard and preserve formatting, but for the last \n
. Eg.: alias clip="head -c -1 | xclip -selection clipboard"
, not too shabby. Now when you pipe ls -l | clip
... All that wonderful output goes to the X-Server clipboard
without a terminating \n
. Ergo ... I can paste that into my next command, just so. Many thanks! –
Signpost head -c -1
instead of head -n -1
, given that we know that it's a newline? –
Postrider head -n -1
removes the last line including its text and still leaves the previous EOL char in the output, so it doesn't do the same thing as head -c -1
–
Deva head -c -1
was what I needed since it is in the middle of a pipeline, perfect thanks –
Deva One way:
wc -l < log.txt | xargs echo -n
echo -n `wc -l log.txt`
–
Colt IFS
) to one space. Example: echo "a b" | xargs echo -n
; echo -n $(echo "a b")
. This may or may not be a problem for the use case. –
Watthour -e
, it will be interpreted as the option to echo
. It's always safer to use printf '%s'
. –
Watthour xargs
is very slow on my system (and I suspect it is on other systems too), so printf '%s' $(wc -l log.txt)
might be faster, since printf
is usually a builtin (Also because there is no information redirection). Never use backticks, they have been deprecated in newer POSIX versions and have numerous drawbacks. –
Naphthalene If you want to remove only the last newline, pipe through:
sed -z '$ s/\n$//'
sed
won't add a \0
to then end of the stream if the delimiter is set to NUL
via -z
, whereas to create a POSIX text file (defined to end in a \n
), it will always output a final \n
without -z
.
Eg:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender
And to prove no NUL
added:
$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72 foo.bar
To remove multiple trailing newlines, pipe through:
sed -Ez '$ s/\n+$//'
sed
doesn't provide -z
. –
Gredel gsed
and use it, by doing what it says here –
Dissolute $
in the beginning of the sed expression does? –
Chao $
is for selecting the last line and thus to avoid executing the sed
command on all lines. See gnu.org/software/sed/manual/sed.html#Numeric-Addresses –
Transducer There is also direct support for white space removal in Bash variable substitution:
testvar=$(wc -l < log.txt)
trailing_space_removed=${testvar%%[[:space:]]}
leading_space_removed=${testvar##[[:space:]]}
trailing_linebreak_removed=${testvar%?}
–
Swear If you want to print output of anything in Bash without end of line, you echo it with the -n
switch.
If you have it in a variable already, then echo it with the trailing newline cropped:
$ testvar=$(wc -l < log.txt)
$ echo -n $testvar
Or you can do it in one line, instead:
$ echo -n $(wc -l < log.txt)
echo -n $(wc -l < log.txt)
has the same effect. –
Busiek printf already crops the trailing newline for you:
$ printf '%s' $(wc -l < log.txt)
Detail:
- printf will print your content in place of the
%s
string place holder. - If you do not tell it to print a newline (
%s\n
), it won't.
"$(command)"
, the internal newlines will be preserved -- and only the trailing newline will be removed. The shell is doing all the work here -- printf
is just a way to direct the results of command substitution back to stdout
. –
Aglow $( )
construct. Here's proof: printf "%s" "$(perl -e 'print "\n"')"
–
Goodfornothing $ printf '%s' "$(wc -l < log.txt)"
–
Gemagemara If you assign its output to a variable, bash
automatically strips whitespace:
linecount=`wc -l < log.txt`
Adding this for my reference more than anything else ^_^
You can also strip a new line from the output using the bash expansion magic
VAR=$'helloworld\n'
CLEANED="${VAR%$'\n'}"
echo "${CLEANED}"
Using Awk:
awk -v ORS="" '1' log.txt
Explanation:
- -v assignment for ORS
- ORS - output record separator set to blank. This will replace new line (Input record separator) with ""
© 2022 - 2024 — McMap. All rights reserved.