How to assert that a string has a newline character and, if so, remove it
The problem is that you have an embedded Carriage-Return (CR, \r
). This causes the terminal text-insertion point to kick back to the start of the line it is printing. That is why you are seeing the 'hello' at the start of the line in you $newVAR
example - sed -n l
displays a readable view of unprintable characters (and end of line).
var=ab$'\r'c ; echo "$var"; printf %s "$var" | sed -n l
# output:
cb
ab\rc$
You can test for it with a simple bash condition check:
[[ $var == *$'\r'* ]] && echo yes || echo no
# output:
yes
You can combine the test and fix in one step by testing for \r
(s) and removing them via:
fix="${var//$'\r'/}"; echo "$var"; echo "$fix"
# output:
cb
abc
The fix uses Shell Parameter Expansion. The particular form used above is for replacing substrings based on your proovided pattern: ${parameter/pattern/string}
<--
This replaces only the first found pattern with string in variable named *parameter. To replace all patterns, you just need to change the first /
to //
.
You can represent \r
as $'\r'
in bash:
if [ "$myvar" = "hello"$'\r' ]; then
echo they are equal
else
echo they are not equal
fi
Or chop the last \r
in myvar
:
if [ "${myvar%$'\r'*}" = "hello" ]; then
echo they are equal
else
echo they are not equal
fi
Curiously, in many shells getopts
is a very likely candidate for a job like this. This may seem counterintuitive at first, but if you consider that getopts
' primary function is to recognize and offer up for interpretation as many specified single character command-line options as might be found in a concatenated series of same, it might begin to make a little more sense.
To demonstrate, from a bash
shell:
x=$(printf '\n\r%010s\t' hello)
OPTIND=1
while getopts : na "-$x"
do printf %q\\n "$OPTARG"
done
$'\n'
$'\r'
\
\
\
\
\
h
e
l
l
o
$'\t'
In that way it can sometimes be convenient to allow getopts
to handle the disassembly as a sort of shell auto-pilot for cases like this. When you do so, you can just screen out unwanted bytes w/ a case
or [
test ]
and build your string back-up from byte 1:
OPTIND=1 y=$(printf \\n\\r) z=
while getopts : na "-$x"
do case $OPTARG in ([!$y])
z=$z$OPTARG
esac
done
printf %q\\n "$z"
$' hello\t'
Given this simple example case - and given a shell which supports the parameter expansions already elsewhere mentioned - said expansions will probably serve you better here. But I thought getopts
might be worth a mention as well in case you weren't aware of its capabilities in this respect. Certainly when I learned of it I found many useful applications for it, anyway.