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
CodePudding user response:
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
andread
. - for each line, extract the filename. Note, done with
sed
since a filename could contain spaces. Thereforecut
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 therm
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.
CodePudding user response:
The following code reads log.txt
line by line, extracts the filename from each line and tries to delete the file. It'll output the original line when the deletion fails, so you can directly generate a new log file containing the entries that haven't been deleted successfully:
#!/bin/bash
while IFS='' read -r line
do
[[ $line =~ ^Uploaded\ (.*)\ at ]] &&
rm -- "${BASH_REMATCH[1]}" ||
echo "$line"
done < log.txt > log.txt.new &&
mv log.txt.new log.txt
remark: the while
loop result is always true unless log.txt
cannot be read or log.txt.new
cannot be generated, so chaining the mv
after a &&
makes it robust