如何编写 bash 脚本来搜索当前目录中的所有文件中的多个字符串?

如何编写 bash 脚本来搜索当前目录中的所有文件中的多个字符串?

我想要一个 bash 脚本:

  1. 对当前目录中的每个文件运行“strings”命令
  2. 使用 grep 在每个文件的字符串输出中搜索特定术语

我有以下内容,但脚本输出没有显示任何匹配项:

#!/bin/bash

echo "Searching files in directory for secrets and urls"

for file in ./*
do
   echo "=====$file====="
   strings ${file} | egrep -wi --color 'secret\|password\|key\|credential|\http'
done

我也尝试过strings $file | egrep -wi --color 'secret\|password\|key\|credential|\http'eval "strings ${file} | egrep -wi --color 'secret\|password\|key\|credential|\http'"但这些似乎不起作用。该脚本输出文件名,但不输出匹配项。

答案1

您使用的egrep与 相同grep -E,即它允许使用扩展正则表达式。

在扩展正则表达式中,|是一个替换(这是您想要使用的),并且\|匹配文字|字符。

因此你想要

grep -w -i -E 'secret|password|key|credential|http'

或者

grep -i -E '\<(secret|password|key|credential|http)\>'

其中\<\>匹配单词边界。

或者

grep -w -i -F \
    -e secret      \
    -e password    \
    -e key         \
    -e credential  \
    -e http

...如果您想进行字符串比较而不是正则表达式匹配。

此外,您将希望始终使用双引号变量扩展。这还允许您正确处理名称包含空白字符(空格、制表符、换行符)的文件以及包含文件名通配符( *, ?, )的文件:[...]

#!/bin/sh

for name in ./*; do
    [ ! -f "$name" ] && continue    # skip non-regular files

    printf '==== %s ====\n' "$name"
    strings "$name" | grep ...
done

也可以看看

答案2

循环for是不必要的。用于strings输出文件名和十进制偏移量,然后将至少三个字符长的任何字符串通过管道传输到egrep

strings -n 3 -f -t d ./* 2> /dev/null | 
egrep '[[:alnum:][:punct:]]*(secret|password|key|credential|http)'\
'[[:alnum:][:punct:]]*$' 

需要三个字符而不是默认的四个字符,以免错过“钥匙”

由于我们缺少示例输入文件,因此这里有一个演示,显示目录中的前十个点击/bin/

strings -n 3 -f -t d /bin/* 2> /dev/null |  
egrep '[[:alnum:][:punct:]]*(secret|password|key|credential|http)'\
'[[:alnum:][:punct:]]*$' | 
head

我的系统上的输出:

/bin/bash:   78590 rl_discard_keymap
/bin/bash:   78720 rl_executing_key
/bin/bash:   79076 rl_bind_key
/bin/bash:   79847 emacs_standard_keymap
/bin/bash:   79905 _rl_keymap
/bin/bash:   81110 _rl_executing_keyseq_size
/bin/bash:   81598 rl_bind_keyseq_if_unbound
/bin/bash:   81640 rl_bind_keyseq
/bin/bash:   81736 bind_keyseq_to_unix_command
/bin/bash:   81863 _rl_dispatching_keymap

相关内容