3

I need to replace characters in the output of a script but they are NOT in the last printed line. They are in the middle of the output.

E.g.

XX----------------------------------------------------------XX
|XXX                                                        |XXX
|  XX                                                       |   XXX
|   XX------------------------------------------------------+-----XXX
|    |                                                              +
|    |     +----------------------------------------------------+   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |            12:34:56  <------+  Characters to replace!  |
|    |     |                                                    |   |
|    |     |     <--------------------------+                   |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
+XX--+     |                                                    |   |
  XX |     +----------------------------------------------------+   |
   XXX                                                              |
     +--------------------------------------------------------------+

the code:

#!/bin/bash

function printThing(){
local timeVar=$(date +"%T")
local lines=(
  '    XX----------------------------------------------------------XX'
  '    |XXX                                                        |XXX'
  '    |  XX                                                       |   XXX'
  '    |   XX------------------------------------------------------+-----XXX'
  '    |    |                                                              +'
  '    |    |     +----------------------------------------------------+   |'
  '    |    |     |                                                    |   |'
  '    |    |     |                                                    |   |'
  '    |    |     |                                                    |   |'
  '    |    |     |                                                    |   |'
  '    |    |     |                                                    |   |'
  "    |    |     |            $timeVar  <------+  Characters to replace!  |"
  '    |    |     |                                                    |   |'
  '    |    |     |     <--------------------------+                   |   |'
  '    |    |     |                                                    |   |'
  '    |    |     |                                                    |   |'
  '    |    |     |                                                    |   |'
  '    +XX--+     |                                                    |   |'
  '      XX |     +----------------------------------------------------+   |'
  '       XXX                                                              |'
  '         +--------------------------------------------------------------+' )

for i in "${lines[@]}"
do
    echo "$i"
done

while :
do
    local timeVar=$(date +"%T")
    #Replace the time in the strings printed above
    sleep 1
done
}

printThing

How would I go about replacing the time value without messing up the whole layout?

  • So, what you are trying to do is print a box and have the time inside it change periodically? – RealSkeptic May 2 '16 at 11:12
  • @RealSkeptic the box is just an example... but yes I just need to replace a string (the time in this case) while it is being surrounded by other characters and lines... – Minzkraut May 2 '16 at 11:17
  • 1
    Depending on your situation and what you're doing, you might want to consider using the "dialog" command, e.g. like this. – Aesin May 2 '16 at 13:49
3

If you have ncurses installed, you can use the tput command to move the cursor to some place on the terminal, where you can use any printing command.

Example:

clear
for i in $(seq 1 40)
do
    echo '##                                                                    ##'
done
for i in $(seq 1 100)
do
    tput cup 20 5
    date
    sleep 1
done

You may want to move the cursor someplace safe before you exit the function, though. For example using

tput cup $(tput lines) 0

Which will move it to the last line of the terminal.

3

For terminals that support it, you could use the save cursor and restore cursor escape sequences:

#! /bin/sh -
save_cursor=$(tput sc) restore_cursor=$(tput rc)
text="\
XX----------------------------------------------------------XX
|XXX                                                        |XXX
|  XX                                                       |   XXX
|   XX------------------------------------------------------+-----XXX
|    |                                                              +
|    |     +----------------------------------------------------+   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |            $save_cursor$(date +%T)  <------+  Characters to replace!  |
|    |     |                                                    |   |
|    |     |     <--------------------------+                   |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
|    |     |                                                    |   |
+XX--+     |                                                    |   |
  XX |     +----------------------------------------------------+   |
   XXX                                                              |
     +--------------------------------------------------------------+"

printf '%s\n' "$text"

while sleep 1; do
  printf %s "$restore_cursor$(date +%T)"
done
1

Maybe something like this solves the issue:

#!/bin/bash                                                                                                                                                                    

function printThing(){

    local timeVar=$(date +"%T")
    local lines="\                                                                                                                                                             
XX----------------------------------------------------------XX                                                                                                                 
|XXX                                                        |XXX                                                                                                               
|  XX                                                       |   XXX                                                                                                            
|   XX------------------------------------------------------+-----XXX                                                                                                          
|    |                                                              +                                                                                                          
|    |     +----------------------------------------------------+   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                       $timeVar                     |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
|    |     |                                                    |   |                                                                                                          
+XX--+     |                                                    |   |                                                                                                          
  XX |     +----------------------------------------------------+   |                                                                                                          
   XXX                                                              |                                                                                                          
     +--------------------------------------------------------------+"

    for i in "${lines[@]}"
    do
        echo "$i"
    done
}

printf "\033c"

while :
do
    timeVar=$(date +"%T")
    printThing
    sleep 1
    printf "\033c"
done
  • this would work... but I'd prefer just replacing the string itself instead of clearing the whole screen and printing everything again... if that's possible – Minzkraut May 2 '16 at 11:18
  • I don't think that is doable in pure Bash! – coffeMug May 2 '16 at 11:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.