1

I have a script that loops over some big collection of data and performs some lenghty operations. Then i need to sort | uniq -c its output. So to let it know that its alive, I print a dot every N items on stderr (very primitive pseudo progress-bar), so it looks pretty much like this:

for i in {1..100}; do 
    [[ $(( (i+=1) % 10)) -eq 0 ]] && echo -n "." >&2
    shuf -i 1-10 -n1
    sleep 0.1
done | sort | uniq -c 

and the output:

..........      9 1
     10 10
      8 2
     14 3
     13 4
      9 5
     11 6
      8 7
      8 8
     10 9

the "progress bar" messes up the output a little - so i was wondering:

  • is there an easy way to add a nweline to that stderr before flushing that stdout? (probably echo >&2 is all I need)
  • or remove it ?

of course in reeality i dont know wow many items there are (at least not out-of-the box). So i was wondering if this can be acieved by some stream redirection

4
  • 1
    FWIW, you can replace [[ $(( (i+=1) % 10)) -eq 0 ]] with [[ 'i++ % 10' -eq 0 ]] or (( i++ % 10 == 0 )). – Stéphane Chazelas Jun 14 at 16:04
  • [ "$(( (i += 1) % 10 ))" -eq 0 ] would be the POSIX one. But then again {1..100} is a zshism and echo -n . is not POSIX either (printf . is the standard equivalent). Not to mention sleep 0.1 (no standard equivalent). – Stéphane Chazelas Jun 14 at 16:44
  • Sounds like you'd rather want ! (( i % 10 )) as i is already incremented in the loop. – Stéphane Chazelas Jun 14 at 16:47
  • that was some pseudo-code... imagine for j in {.....} and rest stays the same ;) – murison Jun 15 at 14:32
4

Wrap the loop in braces (or parentheses) and put the extra echo inside them:

{ for i in {1..100}; do 
    [[ $(( (i+=1) % 10)) -eq 0 ]] && echo -n "." >&2
    shuf -i 1-10 -n1
    sleep 0.1
done; echo >&2; } | sort | uniq -c 

With the whole brace group redirected to sort, it has to wait for everything inside to exit before seeing an end-of-file so it can proceed. That ensures the newline is printed before any of the output from sort and uniq.

1
  • maaaaaaaa, you are my hero ;) it was THAT simple, and I yet couldnt figure it out :P thanks very much! – murison Jun 14 at 15:56

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.