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"