我想要一个 bash 脚本:
- 对当前目录中的每个文件运行“strings”命令
- 使用 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