我已经导出了 10 年的电子邮件档案,该档案非常大。
我想解析任何 64 个字符长的字符串的所有文本,以搜索比特币私钥。
如何解析一定长度的字符串?
答案1
如果您打算搜索十六进制形式的 256 位数字(范围中的 64 个字符0-9
-A-F
比特币私钥可能出现的格式之一),则应执行以下操作:
egrep -aro '\<[A-F0-9]{64}\>' files and dirs ...
添加选项,或者如果某些键是小写的,-i
还包括范围。a-f
对于查找具有指定长度的同一类中的字符串的一般问题,您最好使用 pcre regexps,它可以与带选项的 GNU grep 一起使用-P
。例如,要查找任何字符集中的大写字母,最小长度为 2,最大长度为 4,并且由非大写字母的字符分隔:
echo ÁRVÍZtűrő tükörFÚRÓgép |
LC_CTYPE=en_US.UTF-8 grep -Po '(?<!\p{Lu})\p{Lu}{2,4}(?!\p{Lu})'
FÚRÓ
替换\p{Lu}
为\p{Ll}
小写字母,\S
非空格等。请参阅这里和这里获取完整列表。
(?<!...)
和(?!...)
是消极的向后看和向前看零宽度断言;例如,当未用和(?<!<)\w(?!>)
括起来时,将匹配“单词”字符。零宽度断言可以通过 实现。<
>
\<
vi
(?<!\w)(?=\w)
答案2
如果你想从 中查找长度为 64 的所有单词/path/to/file
,你可以使用
tr -c '[:alnum:]' '\n' < /path/to/file | grep '^.\{64\}$'
这会将所有非字母数字字符替换为换行符,因此每个单词都在自己的行上。然后它过滤此结果以仅包含长度为 64 的单词。
答案3
如果您有 GNU grep
(Linux 上默认),您可以执行以下操作:
grep -Po '(^|\s)\S{64}(\s|$)' file
启用-P
Perl 兼容正则表达式,它为我们提供\b
(字边界)\S
(非空白)和{N}
(精确查找 N 个字符),以及-o
“仅打印该行的匹配部分”的意思。然后,我们寻找非-的延伸。空格的长度正好是 64 个字符,位于行的开头 ( ^
) 或空格 ( 's
) 之后,并且位于行的末尾 ( $
) 或以另一个空格字符结束。
请注意,结果将包含字符串开头和结尾的任何空白字符,因此如果您想进一步解析它,您可能需要使用它:
grep -Po '(^|\s)\K\S{64}(?=\s|$)'
这将查找空白字符或字符串的开头(\s|^)
,然后丢弃它\K
,然后查找 64 个非空白字符,后跟((?=foo)
称为“展望" 并且不会包含在匹配中)空白字符或行尾。
答案4
看来 grep 是“搜索”字符串的正确工具。剩下要做的就是用正则表达式定义这样的字符串。第一个问题是定义单词的范围。它不像“空格”那么简单,用作a book, a lamp
单词,
分隔符,在相同的概念中,许多其他字符,甚至行的开头或结尾都可以充当单词分隔符。 GNU grep 中有一些单词分隔符:
\<
词开始。\>
词末。\b
词边界。
他们都假设一个单词是一个[a-zA-Z0-9_]
字符序列。如果这对你来说没问题,这个正则表达式可以工作:
grep -o '\<.\{64\}\>' file
如果您可以使用扩展正则表达式,则\
可以减少:
grep -oE '\<.{64}\>' file
从“单词开头”( \<
)、64 ( {64}
) 个字符 ( .
) 到“单词结尾”( \>
) 进行选择,并仅打印匹配的 ( -o
) 部分。
然而,点(.
) 将匹配任何性格,可能太过分了。
如果您想更严格地选择(十六进制数字),请使用:
grep -oE '\<[0-9a-fA-F]{64}\>' file
这将允许小写的十六进制数字或者大写。但如果您确实想严格一些,因为可能包含一些非 ASCII 字符,请使用:
LC_ALL=C grep -oE '\<[0-9a-fA-F]{64}\>' file
grep 的某些实现(如 grep -P)没有“单词开头”或“单词结尾”(如\<
和\>
),但有“单词边界”(如\b
):
grep -oP '\b[0-9a-fA-F]{64}\b' file