0

I have a list of many many letsencrypt renew cron files. Each file has a cron schedule that I'm trying replace the hour and minute to be later in the middle of the night. I am trying to do this with a bash script and using sed to update just the hour and minute. For the bloody life of me, I can't get the darn sed to replace. I've tried to look over many of the forums but I can't quite get the right setup. Here's what I got:

for FILE in $(find ./renew -type f -name "letsen*") 
do
        # This will be the new min / hour
        TIMESET="$(($RANDOM % 59 + 0)) $(($RANDOM % 10 + 2))";
        sed -e 's/[0-9]+\W[0-9]+})/$TIMESET/' $FILE;
done

Here's an example of the letsencrypt file:

33 19 * * 5 root /bin/bash /home/forge/.letsencrypt-renew/711959 > /home/forge/.letsencrypt-renew/711959.out$

What am I missing? Appreciate any help!

UPDATE

Thanks to Edgar Magallon, here's the solution that worked for me:

for FILE in ./renew/letsen*
  do
        [[ -f $FILE && ! -L $FILE ]] && {
          TIMESET="$(($RANDOM % 59 + 0)) $(($RANDOM % 10 + 2))";
          
          # I think it's best to do a backup like what was suggested.
          sed -i'.bak' -Ee "s/[0-9]+[0-9]+/$TIMESET/" "$FILE";
        }
done

echo "Done! Have a great day~!";
2
  • Why do you have }) in your sed command? What you want to change is 33 19 to the value stored in $TIMESET or am I wrong? Nov 18 at 23:12
  • @EdgarMagallon dang it. My bad. I was trying to do some fancy regex and left that in. You are right though. I want to replace 33 & 19 with the new $TIMESET value.
    – cbloss793
    Nov 21 at 16:30

1 Answer 1

1

You should not use find to iterate over a list of files. See Why is looping over find's output bad practice?

You can use a simple for loop to iterate over the list of file with name letsen*. And you can replicate -type f by using [[ -f $FILE ]].

About the sed command I see you are using single quotes ' but as you want to replace the hour and minute with $TIMESET then you should use double quotes ". See also this: Difference between single and double quotes in bash. You should use -E option in sed to be able to use extended regular expressions.

I'm not sure why you have }) in /[0-9]+\W[0-9]+})/. I will assume that's not necessary. Because If I'm not wrong you want to replace 33 19 with the value stored in $TIMESET.
Presuming that you want to replace those values as I said before then your code should look like this:

for FILE in ./renew/letsen*
do
        [[ -f $FILE ]] && {
        # This will be the new min / hour
        TIMESET="$(($RANDOM % 59 + 0)) $(($RANDOM % 10 + 2))";
        sed -Ee "s/[0-9]+\W[0-9]+/$TIMESET/" "$FILE"
        
        #Or I guess you can remove '\W' and use a single space.
        #I'm not sure if cron files have always a space between those numbers.
        #If so, then you could use this:
        sed -Ee "s/[0-9]+ [0-9]+/$TIMESET/" "$FILE"
      
        }
done

If you want to edit every file in place you should add -i option to the sed command:

#If you want to backup every file:
sed -i'.bak' -Ee "s/[0-9]+\W[0-9]+/$TIMESET/" "$FILE"
#Without  backup
sed -i -Ee "s/[0-9]+\W[0-9]+/$TIMESET/" "$FILE"
5
  • 1
    For correctness, [[ -f file ]] is more like the -xtype f of GNU find or looping over letsen*(N-.) instead of letsen*(N.) in zsh. It checks for the type of the file after symlink resolution (and succeeds if it finds the file then to be a regular file). Nov 18 at 23:32
  • @StéphaneChazelas that's useful. I had no idea about that. Is there a more effective way to replicate -type f using bash? Another posible solution to this is using -exec to the find command and I guess it should be more effective. Nov 18 at 23:58
  • 1
    -type f would be [[ -f $file && ! -L $file ]] but in many cases, you do want symlinks to regular files to be treated as regular files. It's good to keep that in mind though and to pause to reflect on what to do with symlinks. Nov 19 at 7:59
  • @StéphaneChazelas nice, that's good. Thank you! Nov 19 at 19:59
  • 1
    I learned so much!! Thanks you guys!!!! I appreciate it!!
    – cbloss793
    Nov 21 at 16:55

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.