【问题标题】:Script: Match and delete lines with specific pattern脚本:匹配和删除具有特定模式的行
【发布时间】:2017-10-20 15:09:27
【问题描述】:

我正在尝试创建一个主词汇表来测试我实验室中特定类型的路由器。我已经知道密码遵循什么特定模式。我使用带有紧缩的字符集 [A-F 0-9] 创建了第一个单词表(“raw_wordlist.txt”)文件,

crunch  8 8 ABCDEF0123456789 -d 3 -o raw_wordlist.txt

witch 生成了一个名为“raw_wordlist.txt”的 4289986800 行文件。

现在我正在尝试进一步缩小词表的范围。

这是一个 sn-p:

193B068D
B9AB0685
B9AB068F
A9AAA69A
B98B069B
B9AB069C
B9AB069D
B9A2069E
B9AB069F

这是我想要达到的目标。

  • 删除所有以 3 个数字字符开头的行(如 193B068D)
  • 删除所有以 3 个数字字符结尾的行(如 B9AB0685)
  • 删除所有包含超过 4 个数值的行(如 B98B069B 或 B9A2069E)
  • 删除所有包含超过 4 个相同字符 [A-F] 值的行(如 A9AAA69A)

目前在 crunch 中没有自动执行此操作的选项,所以我唯一的选择是先创建一个基本词表,然后再使用脚本缩小范围。

我尝试过类似的解决方案

sed -e '/^[0-9]{3}/d' -e '/[0-9]{3}$/d' raw_wordlist.txt > hexwordlist.txt

witch 可以解决前导数和尾数问题,但我仍然要弄清楚如何根据字符数来消除。

我不知道如何使用 sed、grep 或 awk 之类的东西,或者使用 pypthon 来实现它?任何帮助将不胜感激!

【问题讨论】:

  • 您的文件是否包含您的示例中的行号?
  • 不,那只是引用主题中的行。
  • @EdMorton 我刚刚注册了该网站,还没有机会了解一切应该如何运作。我想我必须展示我到目前为止所做的尝试。我是一名试图进入安全和脚本的网络管理员。对不起,如果我留下了错误的印象。
  • 当然可以。感谢您的指导。

标签: python bash awk sed grep


【解决方案1】:

让我们从带有 BRE(基本正则表达式)的 sed 解决方案开始:

sed '/^[0-9]\{3\}\|[0-9]\{3\}$\|[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*\|\([A-F]\).*\1.*\1.*\1.*\1.*/d' file

输出(对于您当前的输入片段):

B9AB068F
B9AB069C
B9AB069D
B9AB069F

  • 整个表达式是一个备用组

  • ^[0-9]{3} - 匹配以 3 位数开头的条目

  • [0-9]$ - 匹配以 3 位数字结尾的条目

  • [0-9].*[0-9].*[0-9].*[0-9].*[0-9].* - 匹配包含至少 5 个数字(超过 4 个)的条目

  • ([A-F]).*\1.*\1.*\1.*\1.* - 匹配包含至少 5 个相同的条目 字母[A-F](4个以上)

  • d - sed 删除匹配行的子命令


另一种 sed 方法(使用 ERE)如下所示:

sed -E '/^[0-9]{3}|[0-9]{3}$|([0-9].*){5}|([A-F])(.*\2){4}/d' file

【讨论】:

  • - [0-9]{3} - 匹配以 3 位数字结尾的条目。我想你的意思是 [0-9]{3}$
  • @RomanPerekhrest 建议添加 grep -vE '^[0-9]{3}|[0-9]{3}$|([0-9].*){5}|([A-F])(.*\2){4}' file 作为解决方案。我敢打赌它会比 sed 更快,并且 OP 提到了巨大的输入文件...
  • @Sundeep,无需为grep 下注——模式匹配永远更快。我只是决定不添加 grep 方法,因为@Cyrus 之前添加了它(我不知道他为什么删除了他的答案)stackoverflow.com/a/44087932/3185459
【解决方案2】:

添加不依赖于正则表达式的解决方案。通过向matchers 列表添加新功能应该相当容易扩展。

#!/usr/bin/python

import collections

inputcontent = """193B068D
B9AB0685
B9AB068F
A9AAA69A
B98B069B
B9AB069C
B9AB069D
B9A2069E
B9AB069F
""".strip()

# Read inputcontent from standard input if you want, otherwise just copy into
# this string.

def starts_with_3_numeric(s):
    return all(c in "0123456789" for c in s[:3])

def ends_with_3_numeric(s):
    return all(c in "0123456789" for c in s[-3:])

def contains_4_numeric(s):
    return len([c for c in s if c in "0123456789"]) > 4

def contains_more_than_4_equal_chars(s):
    count = collections.Counter(s)
    return max(count[c] for c in s) > 4

matchers = [
    starts_with_3_numeric,
    ends_with_3_numeric,
    contains_4_numeric,
    contains_more_than_4_equal_chars,
]

filtered = [line.strip()
            for line in inputcontent.splitlines()
            if not any(matcher(line.strip()) for matcher in matchers)]

for outline in filtered:
    print outline

【讨论】:

    【解决方案3】:

    FWIW 下面是您使用 GNU awk 执行 patsplit()(或 FPAT)的方法:

    $ cat tst.awk
    /^[0-9]{3}|[0-9]{3]+$/ { next }
    gsub(/[0-9]/,"&") > 4  { next }
    {
        delete cnt
        patsplit($0,tgt,/[A-F]/)
        for (i in tgt) {
            if ( ++cnt[tgt[i]] > 4 ) {
                next
            }
        }
    }
    { print }
    
    $ awk -f tst.awk file
    B9AB068F
    B9AB069C
    B9AB069D
    B9AB069F
    

    它比 sed 需要更多的代码,因为与 sed 不同,awk 不支持正则表达式中的反向引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-30
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      相关资源
      最近更新 更多