I am trying to make a little bash script, that calls a command on each of my files in have in a file, found with the find
command.
I want to be able to keep track of where the script stopped (it tends to crash) so i can take back from there. I managed to read my file, get the lines,... But currently i'm stuck at the for loop. I want to do a C style for loop, starting at the the last line i stopped at, increment by one, and do it as long as i'm smaller than the number of lines. I got this :
#!/bin/bash
LINES=$(wc -l < file.txt)
LASTLINE=$(grep -P '### Stop marker ###' file.txt | wc -l)
STARTFROM=$(($LINES - $LASTLINE))
for ((i = STARTFROM; i < LINES; i++));
do
echo "we are processing file number $i"
file=sed -n $i'p' file.txt
ocrmypdf [some stuff] -input $file
done
Here is an excerpt of what my file.txt
looks like inside
./input_folder/hard_blurry.pdf
./input_folder/l_ordre_malte.pdf
### Stop marker ###
./input_folder/single_page.pdf
./input_folder/very_hard.pdf
When i run this i get... nothing. Bash doesn't enter the loop at all. I tried setting ints directly, and it worked, which tells me that the vars are bein read as string.
I tried all these ways to write my var :
for ((i = STARTFROM; i < LINES; i++));
for ((i = $((STARTFROM)); i < $((LINES)); i++));
for ((i = $(echo STARTFROM); i < $(echo LINES); i++));
and nothing works. I'm suprised that no erros are thrown as well. My Os is ubuntu 20.0.4
Its content is the path to the files i want to work with.
Any ideas ? Thanks
grep
ping, for line counting and finally for the actual task? I'd suggest to do awhile
loop overread
ing the file, set a flag on theStop marker
line and perform "some stuff" after the marker was set. – Philippos Apr 19 '21 at 06:53LASTLINE
is always 1 or how many "Stop Makers" do you have? – pLumo Apr 19 '21 at 07:07//some stuff
? Also make sure to read What is the XY Problem? and tell us about your "little bash script" which fails. – pLumo Apr 19 '21 at 07:08echo "i is $i"
– Orsu Apr 19 '21 at 07:18grep
more than once each time i run the script. I'm also concerned about huge files – Orsu Apr 19 '21 at 07:24LASTLINE=$(grep -P '### Stop marker ###' file.txt | wc -l)
is not the line number, but the number of Stop markers in your file. And-P
is not needed, you have a fixed string. – pLumo Apr 19 '21 at 07:33echo
your variables before thefor
loop...$LASTLINE
might be 0 (e.g. because your Stop Marker is not found. Then you'd haveLINE == STARTFROM
, which would explain that the loop is not entered. – pLumo Apr 19 '21 at 07:40grep -n
. e.g.grep -n -F '### Stop marker ###' file.txt | head -n 1 | cut -d: -f1
. But it's much easier to use awk. e.g.awk '/### Stop marker ###/ {print NR; exit}' file.txt
– cas Apr 19 '21 at 07:49set -o errexit
(abort on nonzero exitstatus),set -o nounset
(abort on unbound variable) andset -o pipefail
(don't hide errors within pipes) could be useful. I actually set those with vim as automatic header whenever I create a new *.sh file. Two of those commands are explained here if you want more info: https://ricma.co/posts/tech/tutorials/bash-tip-tricks/ . – jeremy Apr 19 '21 at 07:52set -x
to print all commands the shell executes, including the values of variables in those commands. Switch debug output off withset +x
. – berndbausch Apr 19 '21 at 11:47process=false; while read line; do if $process; then YOUR_PROGRAM_TO_DO_STUFF_WITH "$line"; fi; if [[ "$line" == "### Stop marker ###" ]]; then process=true; fi; done < file.txt
. That said, if that "some stuff" can be done with python, use python for the file processing as well. – Philippos Apr 19 '21 at 11:50https://shellcheck.net
, a syntax checker, or installshellcheck
locally. Make usingshellcheck
part of your development process. – waltinator Apr 19 '21 at 17:41some stuff
directly fromfind
using-exec
. It is unclear what you want to achieve with your script. The computations that you seem to want to carry out makes no sense from the point of view of wanting to continue processing from some stop point. – Kusalananda Apr 21 '21 at 06:56