0

I am trying to create a script and I am stuck on the final part I want to add.

The script syncs some paths on my server to my google drive. If there are any deleted or modified files on my server it is moved to /old/date/ path on gdrive.

oldlog="/boot/logs/old-log.txt"
del=""
date=$(date +"%Y-%m-%d-%H%M")
--backup-dir "${dest}/old/${date}"

This works really well, but I have to delete files in /old/ manually and that is what I want to change.

So what I need is for $date to be written to $oldlog and always at line 1 in the log and move all other lines in the log one line down. The $date written to log has to match the $date in --backup-dir "${dest}/old/${date}" so they are identical.

So the log needs to work like this after xx day 1 day

2019-07-01-1800

2 day

2019-07-02-1800
2019-07-01-1800

3 day

2019-07-03-1800
2019-07-02-1800
2019-07-01-1800

So for the next part. After the log is updated like in the example above I need to grab line 21 from oldlog.txt, delete the line and add it to the script as $del.

oldlog="/boot/logs/old-log.txt"
del=
rclone purge "${dest}/old/${del}"

Now, if the line is empty I need it to be just a random text so it wont purge everything inside /old/ or maybe I more advanced approach is possible for it? Something like if del=empty then show message nothing to purge. If del=value from oldlog.txt then run rclone purge "${dest}/old/${del}"

oldlog="/boot/logs/old-log.txt"
del=
delempty=echo "nothing to purge today"
delvalue=rclone purge "${dest}/old/${del}"

Is any of this possible to make in a script without it being to complex?

  • Looks like what you really want to do is to delete files older than a certain date. I recommend skipping the sed script and just using a find command, e.g. https://unix.stackexchange.com/q/218545/135943 – Wildcard Jul 29 '19 at 20:01
  • Yes. I want to delete all folders with all subfolders and files if they were created 21 days ago or more. – prophetse7en Jul 30 '19 at 21:46
  • So then find /old -ctime +21 -delete or similar. (Warning: test and read documentation before using deletion commands from the internet!) – Wildcard Jul 30 '19 at 22:58

1 Answers1

0

You have four things you're trying to accomplish: 1) insert a line at the beginning of a file, 2) reading a specific line of a file, 3) conditionally branching if that specific line does not exist, and 4) deleting a specific line of a file.

You can use the stream editor utility sed to do all of this. I'll assume GNU sed in my answer, but the exact syntax may be slightly different with other versions of sed.

To insert the line at the beginning of the file:

sed -i "1i\${date}" ${oldlog}

The -i option tells sed to work on the file in place. 1 tells sed to only operate on the first line. i\ tells sed to insert before the line.

To retrieve the 21st line:

del="$(sed -n 21p "${oldlog}")"

-n puts sed in quiet mode only so the only output is what is explicitly printed. 21 is the line number and p is the print command.

To determine if there is a 21st line:

sed -n 21q1 ${oldlog}

Again -n puts sed in quiet mode, 21 selects the 21st line, q tells sed to quit, and 1 is the exit code.

To delete the 21st line:

sed -i 21d ${oldlog}

Again, -i to operate on the file in place, 21 selects line 21 and d deletes the line.

Putting it all together:

sed -i "1i\${date}" ${oldlog}
del="$(sed -n 21p "${oldlog}")"
sed -n 21q1 ${oldlog} || { echo "Deleting ${dest}/old/${del}" && rclone purge "${dest}/old/${del}" && sed -i 21d ${oldlog} }
robartsd
  • 223
  • That looks awesome and cant wait to test it. What happens if there is no line 21 in the oldlog file? Will it send purge "${dest}/old/" since the $del is empty and then delete everything inside/old/`? – prophetse7en Jul 26 '19 at 22:43
  • I haven't tested this yet either. I'm not 100% that the nested expansion syntax in the line that sets $del is correct. To prevent the purge, I've used the conditional || operator. Commands after the || only run if the command before fails (returns an error exit code). Another feature is that the && prevents the command deleting the old line unless the purge returns successful. – robartsd Jul 26 '19 at 23:02
  • Looks like it should work, but del="$(sed -n 21p "${oldlog}")" would be better. https://unix.stackexchange.com/questions/118433/quoting-within-command-substitution-in-bash – robartsd Jul 26 '19 at 23:09
  • Thank you so much. One final thing. Is it possible to add a message to all of this? If purge command is started then echo "Deleting backup from ($del)..." – prophetse7en Jul 26 '19 at 23:23
  • Just add another && in the string of commands. Of course if the echo fails, now it won't do the purge. – robartsd Jul 26 '19 at 23:32
  • Sure, but that is ok. Only need a message if it does purge anything :) – prophetse7en Jul 26 '19 at 23:39
  • Just wondering. Wont this write date to oldlog each time? Lets say no files is deleted or changed on my server, then nothing is moved to /old/ og google drive. Still the logs will update with $date and add an entry to the oldlog.

    So lets say there are no changes on my server for 10 days then the logfile will still have 10 lines since the backup script is done once a day?

    – prophetse7en Jul 27 '19 at 00:24
  • I got to test it. It dont update the logfile with $date, it just stays empty. Also the purge command is run regardles of there being a line 21 or not, so this will purge entire /old/ folder. – prophetse7en Jul 27 '19 at 07:47
  • I think sed needs a line one to insert before for the new date to be added. Need to add grouping to my code to get the correct behavior of the last line. – robartsd Jul 29 '19 at 18:05
  • Now it adds "$date" in writing, but not $date in like 2019-30-7-1800

    date=$(date +"%Y-%m-%d-%H%M")

    – prophetse7en Jul 30 '19 at 21:44