grep/ack on Mac OS X 查找多个字符串和相关文件类型

grep/ack on Mac OS X finding multiple strings and respecting file types

我想 运行 grep 在 Mac OS X 上满足以下条件:

方法

我正在考虑使用 this discussion 并从以下 grep 语法开始:

grep --include=*.R -r setHeader .

然后结合以下内容:

grep 'word1\|word2\|word3' /path

但是,对于确保正确评估上述所有标准的意见,我将不胜感激。

群组

^(.*)(facet|map)(.*)(map|facet)(.*)$

regex101


确认

运行 ack -f 表明将搜索 *.R 个文件,因此将接受使用 ack 的解决方案。例如,运行宁:

ack wordA --colour -i -H --rr

得到关于 wordA 的预期结果。我正在考虑将它与讨论的解决方案结合起来 here 但我想使用 AND 而不是 OR 并忽略字符串的顺序可能会出现。我进一步尝试:

ack --match wordA --match wordB  --colour -i -H --rr

但这只产生了 wordB 的结果。

嗯,这效率很低,但假设您不是在搜索大目录,这应该可行。

find . -iname "*.r"  | while read file
do 
if (grep -qi "wordB" $file && grep -qi "wordA" $file)
  then
  echo "======== $file ======="
  grep --color=auto -iE "wordA|wordB" $file
  fi
done

这是一个结合了 closely-named awkack 命令的脚本:

find . -iname '*.r' | while read file; do
    awk '
        BEGIN { IGNORECASE=1; sawWordA = 0; sawWordB = 0 }
        /wordA/ { sawWordA = 1 }
        /wordB/ { sawWordB = 1 }
        sawWordA && sawWordB { exit } # stop reading lines if both matches seen
        END { exit !(sawWordA && sawWordB) }
        ' \
        "${file}" \
    && ack --nofilter -H -i 'wordA|wordB' "${file}"
done

awk 命令...

  • 只列出同时出现两个字符串的文件,而不考虑顺序
  • 忽略大小写

...和 ​​ack 命令...

  • 打印字符串出现的行
  • 用颜色突出显示找到的单词
  • 将文件名打印为 header 并在 header 下的行受 ack 选项的启发
  • 忽略大小写

如果有搜索字符串匹配,awk 脚本会设置标志。如果两个字符串都匹配,则代码段 exit !(sawWordA && sawWordB) 将 return 0。如果 awk returns 0,则运行 ack 命令。

ack --nofilter 选项告诉 ack 避免从 STDIN 读取。否则,ack 将尝试使用 read 命令正在使用的 STDIN。

在评论中,Konrad 询问如何在 shell 脚本中传递变量时使用上述代码。下面是一个例子:

#!/bin/sh

if [ $# -ne 2 ]; then
    echo Usage: [=11=] {string1} {string2}
    E_BADARGS=65
    exit $E_BADARGS
fi

find . -maxdepth 1 -iname '*.r' | while read file; do
    awk "
        BEGIN { IGNORECASE=1; sawArg1 = 0; sawArg2 = 0 }
        // { sawArg1 = 1 }
        // { sawArg2 = 1 }
        sawArg1 && sawArg2 { exit } # stop reading lines if both matches seen
        END { exit !(sawArg1 && sawArg2) }
        " \
        "${file}" \
    && ack --nofilter -H -i "|" "${file}"
done

以上示例没有对提供给脚本的参数中的任何特殊字符进行转义。如果需要转义,可以根据需要修改脚本。