Monday, September 5, 2022

[SOLVED] Execute rm with string on file and delete line

Issue

I have a file (log.txt) with multiples lines.

Uploaded 1Y3JxCDpjsId_f8C7YAGAjvHHk-y-QVQM at 1.9 MB/s, total 3.9 MB
Uploaded 14v58hwKP457ZF32rwIaUFH216yrp9fAB at 317.3 KB/s, total 2.1 MB

Each line in log.txt represents a file that needs to be deleted. I want to delete the file and then delete the respective line.

Example:

rm 1Y3JxCDpjsId_f8C7YAGAjvHHk-y-QVQM

and after deleting the file that the log.txt contains, delete the line, leaving only the others.

Uploaded 14v58hwKP457ZF32rwIaUFH216yrp9fAB at 317.3 KB/s, total 2.1 MB

Solution

Try this:

#!/bin/bash

logfile="logfile.txt"
logfilecopy=$( mktemp )
cp "$logfile" "$logfilecopy"

while IFS= read -r line
do
    filename=$( echo "$line" | sed 's/Uploaded \(.*\) at .*/\1/' )
    if [[ -f "$filename" ]]
    then
        tempfile=$( mktemp )
        rm -f "$filename" && grep -v "$line" "$logfile" >"$tempfile" && mv "$tempfile" "$logfile"
    fi
done < "$logfilecopy"

# Cleanup
rm -f "$logfilecopy"

It does:

  • keep a copy of the original log file.
  • read each line of this copy using while and read.
  • for each line, extract the filename. Note, done with sed since a filename could contain spaces. Therefore cut would not work as required.
  • If the file exists, delete it, remove the line from the log file and store it in a temporary file, move the temporary file into the log file.
  • that last step is done with && between commands to ensure that the last command is done before continuing. If the rm fails, the log entry must not be deleted.
  • finally delete the original log file copy.
  • you can add echo statements and-or -x to $!/bin/bash to debug if required.


Answered By - Nic3500
Answer Checked By - Senaida (WPSolving Volunteer)