如何使这个脚本只grep第一行

时间:2015-10-02 14:14:25

标签: bash grep xargs

for i in USER; do
    find /home/$i/public_html/ -type f -iname '*.php' \
    | xargs grep -A1 -l 'GLOBALS\|preg_replace\|array_diff_ukey\|gzuncompress\|gzinflate\|post_var\|sF=\|qV=\|_REQUEST'
done

忽略了-A1。最终的结果是我只想让它向我展示包含任何匹配单词的文件,但仅限于脚本的第一行。如果有一个更好的,更有效的资源密集型方式,那么这将是非常大的共享服务器上运行。

3 个答案:

答案 0 :(得分:1)

改为使用awk

for i in USER; do
    find /home/$i/public_html/ -type f -iname '*.php' -exec \
     awk 'FNR == 1 && /GLOBALS|preg_replace|array_diff_ukey|gzuncompress|gzinflate|post_var|sF=|qV=|_REQUEST/
          { print FILENAME }' {} +
done

如果第一行匹配,这将打印当前输入文件。它并不理想,因为它会读取每个文件的所有内容。如果您的awk版本支持它,则可以使用

awk '/GLOBALS|.../ { print FILENAME } {nextfile}'

nextfile命令将针对第一行执行,有效地在awk测试后跳过文件的其余部分,如果它与正则表达式匹配。

答案 1 :(得分:0)

for j in (find /home/$i/public_html/ -type f -iname '*.php'); 
    do result=$(head -1l $j| grep $stuff ); 
    [[ x$result |= x ]] && echo  "$j: $result"; 
done

您需要更多努力才能跳过租赁空白行。 Fgrep将节省资源。 一点perl会带来很大的改进,但很难在手机上输入它。

编辑: 在一个不太局促的键盘上,插入不那么简短的解决方案。

答案 2 :(得分:0)

以下代码未经测试:

for i in USER; do
    find /home/$i/public_html/ -type f -iname '*.php' | while read -r; do
        head -n1 "$REPLY" | grep -q 'GLOBALS\|preg_replace\|array_diff_ukey\|gzuncompress\|gzinflate\|post_var\|sF=\|qV=\|_REQUEST' \
            && echo "$REPLY"
    done
done

想法是遍历每个find结果,显式测试第一行,如果找到匹配则打印文件名。我不喜欢它,因为它感觉很笨重。