Delete a file if multiple conditions are met
checkfile() {
awk '
BEGIN {
FS = ":"
status = 1
ports[80] = 1
ports[443] = 1
}
NR == 3 || !($2 in ports) {status = 0; exit}
END {exit status}
' "$1"
}
file=portscan.txt
checkfile "$file" || echo rm -- "$file"
That awk command will exit with status 0 if the file has a 3rd line, or if it sees a "non-standard" port.
If the function returns non-zero (the file has <= 2 lines and only "standard" ports), then the rm command is printed.
Remove echo
if the results look right.
Alternately:
checkfile() {
# if more than 2 lines, keep the file
(( $(wc -l < "$1") > 2 )) && return 0
# if a "non-standard" port exists, keep the file
grep -qv -e ':80$' -e ':443$' "$1" && return 0
# delete the file
return 1
}
or, more tersely
checkfile() {
(( $(wc -l < "$1") > 2 )) || grep -qv -e ':80$' -e ':443$' "$1"
}
Ok, try this
[~/my_learning/lint]$ cat file.txt
somedomain.com:80
somedomain.com:443
[~/my_learning/lint]$ cat file_dont_delete.txt
somedomain.com:8443
somedomain.com:443
[~/my_learning/lint]$ for file in file.txt file_dont_delete.txt
do
num_of_lines=$(wc -l $file| xargs | awk '{print $1}')
port_scan=$(awk -F':' '{ if (($2 == "443") || ($2 == "80")) print "matched" }' $file | wc -l | xargs)
if [ $num_of_lines -le 2 ] && [ $num_of_lines -eq $port_scan ] ; then
echo "$file can be deleted"
else
echo "$file can't be deleted"
fi
done
# Output
file.txt can be deleted
file_dont_delete.txt can't be deleted
I follow the below conditions
- number of lines 2 or less than or 2.
- and for each line, I used awk to extract field 2 which is a port and check if it is either 80 or 443, and on any, I am printing
matching
. - Then I am counting how many matching occurred.
- As per your description, even a single port that is not from 80 or 443 is presented, then I shouldn't delete the file.
Thank you for giving me this opportunity of writing the shell code.
Solution based on mapfile:
#!/bin/bash
shopt -s extglob
mapfile -tn3 a < $1
[[ ${#a[@]} -lt 3 ]] && { \
[[ ${#a[@]} -gt 0 && ${a[@]/%:@(80|443)} =~ :[0-9]+ ]] || echo rm -v -- $1; }
Pure bash solution, wrapped in a function and easy to read:
#!/bin/bash
possiblyDeleteFile() {
local count=0
local rLine port
local otherPort=false
while IFS= read -r -d'' rLine; do
port="${rLine#*:}"
((count++))
if [ "$port" != 80 ] && [ "$port" != 443 ]; then
otherPort=true
fi
done < "$1"
if [ $count -le 2 ] && ! $otherPort; then
echo "Deleting file $1"
rm -- "$1"
fi
}
possiblyDeleteFile "$1"