shell 查找包含pattern1的文件,其中下一行不包含pattern2

2nbm6dog  于 2023-03-13  发布在  Shell
关注(0)|答案(2)|浏览(178)

我正在尝试搜索纯文本私钥。简单搜索“开始.*PRIVATE”会返回许多误报,因为许多都是以以下格式加密存储的:

-----BEGIN ... PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED

期望的输出是包含明文私钥的所有文件名的列表。一个文件中有多少个,或者每个发生的频率是我以后要处理的问题。
我有一个非常丑陋,恼人的脆弱的解决方案:

for i in $(find temp_git/ -type f) ; do sed -n '/BEGIN.*PRIVATE/ {N ; /ENCRYPTED/!p}' "${i}" | sed -E "s#.*#${i} : Plaintext PK#" | sort -u 2>/dev/null ; done

由于最后一条sed语句中的路径引用不够,这在不同的文件名上都失败了,我不愿意在一个明显次优的解决方案上投入更多的时间。使用sed确实可以简洁地做到这一点,但由于无法与awk一起破解任何有用的东西,我对 *awk解决方案非常感兴趣(使用awk,我想我还可以删除'for i in subshell...')。

chhkpiq4

chhkpiq41#

Perl来拯救我们!

find temp_git -exec perl -lne '
    print $ARGV if /BEGIN.*PRIVATE/ and readline !~ /ENCRYPTED/
' {} +
  • -l从Perl的输入中删除换行符并将其添加到print;
  • -n逐行处理输入,运行每一行的代码;
  • $ARGV包含当前打开文件的名称;
  • readline从文件中读取下一行,!~否定与/ENCRYPTED/的匹配。
f3temu5u

f3temu5u2#

这可能对您有用(GNU sed):

sed -n '/BEGIN.*PRIVATE/{N;/\n.*ENCRYPTED/!F;D}' file

使用选项-n关闭隐式打印。
如果一行包含BEGIN,然后包含PRIVATE,则追加下一行。
如果附加行不包含ENCRYPTED,则输出文件名。
要与find一起使用:

find . -exec sed -n '/BEGIN.*PRIVATE/{N;/\n.*ENCRYPTED/!F;D}' '{}' \;

相关问题