如果满足多个条件则删除文件

如果满足多个条件则删除文件

我需要的

我有一个现有的脚本,可以提取域的端口信息并将其存储到名为的文本文件中portscan.txt。示例:

portscan.txt文件:

somedomain.com:80
somedomain.com:443

我希望仅在满足某些条件时才删除信息。这些条件包括:

  • 包含域名的文件应该不超过 2 行
  • 端口应该只能是 80 或 443(即,如果文件中存在 8080、8443 或任何其他端口,我就不想删除该文件)。

笔记:因此基本上,上面提供的示例文件应该被删除,但如果有两行,我不想删除该文件,但端口是 8080 或 8443(或任何其他端口)例如:

somedomain.com:8443
somedomain.com:443

这应该不是被删除。

我尝试过

我尝试编写脚本,结果如​​下:

#!/bin/bash

lines=$(cat portscan.txt | wc -l)
ports=$(cat portscan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


if [[ $lines < 3 ]] && [[ $ports != 80 ]]; then
    if [[ $ports != 443 ]]; then
        echo "I need to delete this"
    fi
else
    echo "I will NOT delete this..."
fi

这是脚本的第二次渲染,我尝试了嵌套如果语句,因为我无法做到这样的条件:

如果portscan.txt 少于两行港口是不是80或者443

我也尝试以一种更简单的方式实现这一点,如下所示:

#!/bin/bash

lines=$(cat portscan.txt | wc -l)
ports=$(cat portscan.txt | grep -Pv '(^|[^0-9])(80|443)($|[^0-9])')


if [[ $lines < 3 ]] && (( $ports != 80||443 )); then
    echo "I need to delete this"
else
    echo "I will NOT delete this..."
fi

我尝试过,((因为我读到这最好与算术函数一起使用——这就是我认为我需要的,但我对条件参数不太熟悉,它应该是这样的:“这或者那”。

希望这是有意义的,任何帮助都将不胜感激!

答案1

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"

如果文件有第三行,或者看到“非标准”端口,则该 awk 命令将以状态 0 退出。

如果函数返回非零(文件有 <= 2 行且只有“标准”端口),则打印 rm 命令。

echo如果结果看起来正确则删除。


交替:

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
}

或者更简洁地说

checkfile() {
    (( $(wc -l < "$1") > 2 )) || grep -qv -e ':80$' -e ':443$' "$1"
}

答案2

好的,试试这个

[~/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

我遵守以下条件

  • 行数 2 或小于或 2。
  • 对于每一行,我使用 awk 提取字段 2(即端口)并检查它是 80 还是 443,如果是,则打印matching
  • 然后我计算一下发生了多少次匹配。
  • 根据您的描述,即使出现了不是 80 或 443 的单个端口,那么我也不应该删除该文件。

谢谢你给我这次编写shell代码的机会。

答案3

基于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; }

答案4

要在 bash 中进行数字比较,您需要使用-gt-lt等。该<符号表示 stdin 重定向。

您可以像移植时一样将行号比较括在 (( )) 中,也可以使用-lt参见https://tldp.org/LDP/abs/html/comparison-ops.html

相关内容