Following this :
I want to put following line into watch cmd.
wc -l myfile | awk '{print "Done ",$1," of 587320"}'
Following above instructions I tried:
watch "wc -l myfile | awk '{print '"'Done '"',\$1,'"' of 587320'"'}'"
But got
awk: cmd. line:1: {print Done ,\, of 587320}
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: {print Done ,\, of 587320}
awk: cmd. line:1: ^ syntax error
Expected output :
Done 57776 of 587320
I'm overwhelmed by the quotes.
Following this : https://superuser.com/questions/276701/using-the-watch-command-with-an-argument-that-contains-quotes
I want to put following line into watch cmd.
wc -l myfile | awk '{print "Done ",$1," of 587320"}'
Following above instructions I tried:
watch "wc -l myfile | awk '{print '"'Done '"',\$1,'"' of 587320'"'}'"
But got
awk: cmd. line:1: {print Done ,\, of 587320}
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: {print Done ,\, of 587320}
awk: cmd. line:1: ^ syntax error
Expected output :
Done 57776 of 587320
I'm overwhelmed by the quotes.
wc -l myfile | awk '{print "Done ",$1," of 587320"}'
You do not need wc -l
as this can be done by GNU AWK
itself, following way
awk 'END{print "Done ", NR, " of 587320"}' myfile
Explanation: END
is executed after all files (in this case one file) is done, NR
built-in variable holds The number of input records awk has processed since the beginning of the program’s execution
I'm overwhelmed by the quotes.
To avoid problem of this kind you might exploit -f
option of GNU AWK
, create file named counter.awk
with following content
END{print "Done ", NR, " of 587320"}
and then you might get same result as above command doing
awk -f counter.awk myfile
which fit easily into watch
command
watch "awk -f counter.awk myfile"
Note: I have tested above solution by running
for i in $(seq 1 100);
do
echo $i >> myfile
sleep 1
done
in other terminal and using watch version procps-ng 3.3.17 AND awk version GNU Awk 5.3.1
Escape the dollar sign and the double quotes, eg:
watch "wc -l myfile | awk '{print \"Done \",\$1,\" of 587320\"}'"
Alternatively, place the code in a script and no escapes are required, eg:
$ cat watch_me
#!/bin/bash
wc -l myfile | awk '{print "Done ",$1," of 587320"}'
$ watch ./watch_me
Running either of the above in terminal #1 against a 6-line file the following is displayed:
Every 2.0s: wc -l myfile | awk '{print "Done ",$1," of 587320"}' ubu22b: Wed Jan 29 19:09:50 2025
Done 6 of 587320
In terminal #2 I added some lines to the file:
printf "7\n8\n9\n10\n" >> myfile
Terminal #1 then updated with:
Every 2.0s: wc -l myfile | awk '{print "Done ",$1," of 587320"}' ubu22b: Wed Jan 29 19:09:50 2025
Done 10 of 587320
As @Daweo said, in your specific case you can rewrite the command to get rid of the |
(and the quoting issues at the same time).
For complex cases, a solution can be to define a shell function, export it and use it with watch
:
show_progress() {
wc -l myfile |
awk '{print "Done ",$1," of 587320"}';
}
export -f show_progress
watch show_progress
remark: watch
runs your login shell, so the script shell and your login shell have to be the same, and that shell needs to be able to export functions.