我需要的
我有一个现有的脚本,可以提取域的端口信息并将其存储到名为的文本文件中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