我正在尝试将以下内容写入 bash 脚本:
#!/bin/bash
find /path/to/file -type f -name "*.html" -exec grep -l "XXXX" '{}' \; -print
其中 XXXX 是应循环此命令的字符串列表。我努力将该脚本的正确部分放入循环中,并且努力将 XXXX 保存到随后循环的变量中。
答案1
您使用了zsh
标签,但有一个#!/bin/bash
shebang。bash
和zsh
是两个不同的外壳。
grep
查找多个字符串的一种方法是使用 来调用它grep -F -e 'first string' -e 'second string' -e'blah'...
。
在 zsh 中,如果数组中有字符串列表:
strings=('first string' 'second string' '***')
你可以做:
使用 GNU grep
:
grep -Frl --include='*.html' -e$^strings .
或者使用find
:
find . -name '*.html' -type f -exec grep -Fl -e$^strings {} +
或者使用 的zsh
递归 globbing 和 glob 限定符:
grep -Fl -e$^strings -- **/*.html(D.)
或者,为了解决系统对参数数量的限制,您可以传递给类似find
's-exec
的命令,以防有很多 html 文件:
autoload -Uz zargs
zargs -- **/*.html(D.) -- grep -Fl -e$^strings --
这还有对文件列表进行排序的优点(您可以通过将oN
glob 限定符添加到N
ot o
rder 来禁用该排序)。
请注意,-l
已经打印(列出)包含至少一个匹配的文件名,添加-print
,因此成功时打印的文件名grep
是多余的,并且意味着文件名被打印两次。
答案2
如果您只想grep
查找该目录中每个 .html 文件中由 XXXX 表示的任何字符串并返回出现任何字符串的文件,那么以下内容就足够了:
egrep -l "string1|string2|string3" /path/to/directory/*.html
grep -El "string1|string2|string3" /path/to/directory/*.html
它们都做同样的事情,但其中一个使用egrep
而不是grep -E
.该-l
开关返回字符串出现的文件,而不是包含该字符串的行。如果您确实需要将字符串分配给变量:
export strings='string1|string2|string3'
egrep -l "$strings" /path/to/directory/*.html
grep -El "strings" /path/to/directory/*.html
答案3
您可以使用包含要查找的字符串的文件:
文件.txt
foo
bar
进而
find /path/to/file -type f -name "*.html" -exec grep -l -f file.txt '{}' \; -print
答案4
如果您想对可用字符串的文件执行任何操作,请使用以下命令:
#!/bin/bash
declare -a STRINGS=$(find /var/www/html/ -type f -name "*.html" -exec grep "this is
test" {} \; -print)
for string in "${STRINGS[@]}"
do
echo "${string}"
echo "${STRINGS}"
done
输出:
[root@awx html]# sh test.sh
this is test file1
/var/www/html/1.html
this is test file2
/var/www/html/2.html
this is test file1
/var/www/html/1.html
this is test file2
/var/www/html/2.html
[root@awx html]#