代码之家  ›  专栏  ›  技术社区  ›  Stan E

一个用于排除异常模式的衬板[关闭]

  •  -2
  • Stan E  · 技术社区  · 6 年前

    我的目标是做一个优雅的 一班轮 .

    输入 :

    源文件,包含字符串列表:

    foo123
    bar12356
    foo999
    var8292
    bar922
    link991
    bar8
    var000
    

    带有黑名单模式的文件:

    bar
    link
    

    白名单文件(可以包含多个条目):

    bar922
    

    任务 以下内容: 我们需要根据黑名单中的模式删除字符串,保留白名单中的精确匹配。关键是我们需要两个 将输出保持与原始文件中相同的顺序 我们 如果初始文件中不存在白名单字符串,则不应添加它们 .

    产量 :

    foo123
    foo999
    var8292
    bar922
    var000
    
    5 回复  |  直到 6 年前
        1
  •  2
  •   kvantour    6 年前

    解决方案 David C. Rankin 非常优雅,不会太乱。如果您想保持排序,可以将其扩展为:

    $ { grep -wf wl file; grep -vf bl file ;} | grep -wf - file
    

    注意我们介绍了 -w 白名单的标志,以确保单词匹配。

    备注:这是一个灵丹妙药的解决方案,它是迄今为止最有效的解决方案!

        2
  •  2
  •   Inian    6 年前

    你可以用这个 awk 命令。这个主意是你用的 paste 黑名单文件上的命令( bl )使其内容由 | ,例如 bar|link 也在白名单上( wl )

    生成文件后,我们对文件的内容执行regex匹配,条件是这些条目可能在白名单中,或者条目不应在黑名单中。

    awk -v bl=$(paste -sd'|' bl) -v wl=$(paste -sd'|' wl) '$0 ~ wl || $0 !~ bl' file
    

    注释中有一个点,用于处理 WL 文件。如果你怀疑他们,一定要用 sed -i '/^$/d' wl .

        3
  •  1
  •   David C. Rankin    6 年前

    你可以创建一个简单的 一班轮 使用 grep -f 从每个白名单和黑名单文件中读取模式,包括 -v 将匹配项与黑色列表反转,然后使用上的组合结果 stdin 创建有序文件,例如

    输入、白名单、黑名单文件

    $ cat file
    foo123
    bar12356
    foo999
    var8292
    bar922
    link991
    bar8
    var000
    

    白名单

    $ cat white
    bar922
    

    黑名单

    $ cat black
    bar
    link
    

    编辑 在与@kvantour进行了交流工作之后,您可以将列表输入到 斯坦丁 利用 过程替换 以获得最终订单,例如,

    $ grep -wof - file < <(grep -v -f black file; grep -f white file)
    foo123
    foo999
    var8292
    bar922
    var000
    
        4
  •  0
  •   Graham    6 年前

    为了好玩,这里有一个使用bash数组的选项 :

    # Gather our lists...
    mapfile -t a < input.txt; mapfile -t wl < wl; mapfile -t bl < bl
    
    # And store the whitelist as indices for easier handling...
    declare -A wl_a=(); for x in "${wl[@]}"; do wl_a["$x"]=1; done
    
    # Then step through the data array,
    for x in "${!a[@]}"; do
      # detecting and skipping whitelist matches,
      [[ "${wl_a[${a[$x]}]}" = 1 ]] &&
        printf 'wl: %s\n' "$x" &&
        continue
      # and deleting blacklist matches.
      for y in "${bl[@]}"; do
        [[ "${a[$x]}" = "$y"* ]] &&
          printf 'bl: %s\n' "${a[$x]}" &&
          unset a["$x"]
      done
    done
    

    结果是数组, ${a[@]} ,按原始顺序包含您的数据,并删除相应的黑名单项。你可以看到结果 declare -p a printf '%s\n' "${a[@]}" .

    注意这是一个 疯子 为了达到这个目的(显然不是一行),你可以在awk中更有效地完成它。但至少这是一个纯粹的bash解决方案,不使用外部工具,yay。

    1。这取决于bash 4+,因为其中一个数组是关联的。

        5
  •  0
  •   stack0114106    6 年前

    使用Perl也可以解决这个问题。

    > cat stan.in
    foo123
    bar12356
    foo999
    var8292
    bar922
    link991
    bar8
    var000
    > cat white
    bar922
    > cat black
    bar
    link
    > perl -lne 'BEGIN{ @w=qx(cat white);@b=qx(cat black);}chomp for(@w);chomp for(@b); $x=$_;print if grep {$x=~/$_/} @w; print if scalar(grep { $x=~/$_/g} @b)==0' stan.in 
    foo123
    foo999
    var8292
    bar922
    var000
    > 
    

    $ perl -lne 'BEGIN{ @w=qx(cat white);@b=qx(cat black);}chomp for(@w,@b);$x=$_;print if grep {$x=~/$_/} @w; print if scalar(grep { $x=~/$_/g} @b)==0' stan.in
    foo123
    foo999
    var8292
    bar922
    var000