level42
level42

Reputation: 987

Truncating "wrapping" long string outputs with prefix, appends new line at the bottom of each dump of the hold space

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

Answers (2)

Ed Morton
Ed Morton

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

choroba
choroba

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

Related Questions