AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1377370
Accepted
Justin Washek
Justin Washek
Asked: 2021-11-25 07:17:40 +0800 CST2021-11-25 07:17:40 +0800 CST 2021-11-25 07:17:40 +0800 CST

满足多个条件时删除文件

  • 772

我需要的

我有一个现有的脚本,它提取域的端口信息并将其存储到一个名为portscan.txt. 例子:

portscan.txt文件:

somedomain.com:80
somedomain.com:443

我只想在满足某些条件时删除信息。这些条件包括:

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

注意:所以基本上,上面提供的示例文件应该被删除,但如果有 2 行,我不想删除该文件,但端口是 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

这是脚本的第二次渲染,我尝试嵌套if语句,因为我无法执行这样的条件:

如果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

我已经尝试过,((因为我读到这更好地与算术函数一起使用——这是我认为我需要的,但当它应该像这样时,我对条件参数并不那么精通:“这个和那个或那个”。

希望这是有道理的,任何帮助将不胜感激!

command-line
  • 5 5 个回答
  • 908 Views

5 个回答

  • Voted
  1. Best Answer
    glenn jackman
    2021-11-25T08:17:43+08:002021-11-25T08:17:43+08:00
    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"
    

    如果文件有第 3 行,或者如果它看到“非标准”端口,则该 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"
    }
    
    • 9
  2. rɑːdʒɑ
    2021-11-25T08:04:40+08:002021-11-25T08:04:40+08:00

    好的,试试这个

    [~/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
  3. rexkogitans
    2021-11-26T06:06:05+08:002021-11-26T06:06:05+08:00

    纯 bash 解决方案,封装在一个函数中并且易于阅读:

    #!/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"
    
    • 1
  4. user986805
    2021-11-26T06:55:47+08:002021-11-26T06:55:47+08:00

    基于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; }
    
    • 1
  5. Steve Folly
    2021-11-25T07:47:35+08:002021-11-25T07:47:35+08:00

    要在 bash 中进行数字比较,您需要使用-gt,-lt等。该<符号用于标准输入重定向。

    您可以像对端口所做的那样将行号比较包含在 (( )) 中,或者使用-lt参见https://tldp.org/LDP/abs/html/comparison-ops.html

    • -2

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve