Reputation: 987
I'm trying to prefix console outputs, while truncating long string outputs to a maximum of 60 characters. (Preventing long lines from bleeding over and breaking the prefix)
How come...
esc=$(printf '\033')
sudo apt upgrade 2>&1 >&1 | sed -e "s/.\{0,60\}/${esc}[35m║ &\n/g"
...is appending a new (un-prefixed) line below each dump of the hold space? How can I stop this behavior, or at least append a prefix to it?
Output:
║
║ WARNING: apt does not have a stable CLI interface. Use with
║ caution in scripts.
║
║ Reading package lists...
║ Building dependency tree...
║ Reading state information...
║ Calculating upgrade...
║ 0 upgraded, 0 newly installed, 0 to remove and 0 not upgrade
║ d.
║
Upvotes: 0
Views: 69
Reputation: 204558
You're replacement string specifically says to add a newline after every 0 to 60 chars so that's what sed is doing and then it's printing a terminating newline at the end of all of it's output as it always does and that's what's causing a blank line to appear. It's easier to see with smaller input and a smaller range:
$ echo '1234' | sed 's/.\{0,2\}/<&>\n/g'
<12>
<34>
$
$ echo '12345' | sed 's/.\{0,2\}/<&>\n/g'
<12>
<34>
<5>
$
There's various ways to solve the problem but you seem to be trying to wrap (aka fold) lines rather than truncate them, so try this instead:
fold -s -w60 | sed "s/^/${esc}[35m║ /"
Here it is using what I think your original output of sudo apt upgrade 2>&1 >&1
probably looked like as input:
$ cat file
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
Calculating upgrade...
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
$ cat file | fmt -s -w60 | sed "s/^/${esc}[35m║ /"
║ WARNING: apt does not have a stable CLI interface. Use
║ with caution in scripts.
║
║ Reading package lists...
║ Building dependency tree...
║ Reading state information...
║ Calculating upgrade...
║ 0 upgraded, 0 newly installed, 0 to remove and 0 not
║ upgraded.
Note that fold
is splitting the input at white space (when it can), whereas your sed command would chop lines mid-word which would create messier output.
Upvotes: 1
Reputation: 242333
You need to replace the whole line with its first 60 characters.
sed -e 's/^\(.\{0,60\}\).*/'"$esc"'[35m║ \1/'
# ~~ ~~^^ ~~
# 1 1 2 3
1
remembers the first 60 characters,2
matches the rest,3
outputs the remembered part.Upvotes: 1