Reputation: 113
When bash displays strings, it interprets the carriage return '^M'
$ echo "1234^Mab"
ab34
I have a script that needs access to the interpreted string "ab34". But I can't find any way to do this. The output stream of the echo command still contains the carriage return character, which means that if a script reads the output, it will still see "1234^Mab", even though the shell displays the string "ab34".
Removing the carriage return is not good enough; It does not result in the string "ab34".
$ echo "1234^Mab" | tr -d '\r'
1234ab
Converting the carriage return to a unix-style newline character doesn't produce the desired result either:
$ echo "1234^Mab" | sed 's/^M/\n/'
1234
ab
Upvotes: 1
Views: 2334
Reputation: 780663
Use the col -b
command to interpret cursor control sequences and return the visible output.
echo $'1234\rab' | col -b
This handles about a dozen different cursor motion sequences, not just carriage return.
Upvotes: 7
Reputation: 206659
Here's a script that "emulates" the carriage-return by processing the input argument character by character. The output is built character by character too, resetting the output index when CR is encountered.
#! /bin/bash
arg="$1"
out=""
cr=$'\r'
j=0
for ((i=0; i<${#arg}; i++)) ; do
char=${arg:$i:1}
if [[ $char = $cr ]] ; then
j=0
else
tmp="${out:0:$j}"$char
((j++))
out="$tmp${out:$j}"
fi
# echo "$out" # to see it in progress
done
echo "Final: $out"
Example:
$ ./t.sh 123456$'\r'abcde$'\r'.:.
1
12
123
1234
12345
123456
123456
a23456
ab3456
abc456
abcd56
abcde6
abcde6
.bcde6
.:cde6
.:.de6
Final: .:.de6
Upvotes: 0