Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex Mac OS X上的grep/ack查找多个字符串并尊重文件类型_Regex_Macos_Bash_Grep_Ack - Fatal编程技术网

Regex Mac OS X上的grep/ack查找多个字符串并尊重文件类型

Regex Mac OS X上的grep/ack查找多个字符串并尊重文件类型,regex,macos,bash,grep,ack,Regex,Macos,Bash,Grep,Ack,我想在Mac OS X上运行grep,它将满足以下标准: 以*.R或*.R作为扩展名搜索所有文件,并忽略其他文件 查找字符串:wordA和wordB说明字符串可能以someRubbishWordARubbish的格式出现(这是有效匹配) 仅列出同时出现两个字符串的文件,与顺序无关 打印字符串出现的行 用彩色突出显示找到的单词 将文件名打印为标题,并在标题下打印行。我的灵感来自于这些选择 无视案件 方法 我正在考虑使用并从以下grep语法开始: grep --include=*.R -r se

我想在Mac OS X上运行
grep
,它将满足以下标准:

  • *.R
    *.R
    作为扩展名搜索所有文件,并忽略其他文件
  • 查找字符串:
    wordA
    wordB
    说明字符串可能以
    someRubbishWordARubbish
    的格式出现(这是有效匹配)
  • 仅列出同时出现两个字符串的文件,与顺序无关
  • 打印字符串出现的行
  • 用彩色突出显示找到的单词
  • 将文件名打印为标题,并在标题下打印行。我的灵感来自于这些选择
  • 无视案件
方法 我正在考虑使用并从以下
grep
语法开始:

grep --include=*.R -r setHeader .
然后将其与以下内容相结合:

grep 'word1\|word2\|word3' /path
但是,我希望能够就确保正确评估上述所有标准发表意见


阿克 运行
ack-f
显示将搜索
*.R
文件,以便接受使用
ack
的解决方案。例如,运行:

ack wordA --colour -i -H --rr
获取有关wordA的所需结果。我想将它与讨论的解决方案结合起来,但我想使用而不是,并忽略字符串可能出现的顺序。我进一步尝试:

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

下面是一个脚本,它结合了名称相近的
awk
ack
命令:

find-在读取文件时使用iname'*.r'|;做
awk'
开始{IGNORECASE=1;sawWordA=0;sawWordB=0}
/wordA/{sawWordA=1}
/wordB/{sawWordB=1}
sawWordA&&sawWordB{exit}#如果两行都匹配,则停止读取
结束{退出!(sawWordA和sawWordB)}
' \
“${file}”\
&&ack--nofilter-H-i'wordA | wordB'${file}
完成
awk命令

  • 仅列出两个字符串出现的文件,与顺序无关
  • 置之不理
…和ack命令

  • 打印字符串出现的行
  • 以彩色突出显示找到的单词
  • 根据ack选项,将文件名打印为标题和标题下的行
  • 置之不理
如果搜索字符串匹配,awk脚本将设置标志。如果两个字符串都已匹配,则代码段将退出!(sawWordA和&sawWordB)将返回0。如果awk返回0,则运行ack命令

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

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

#/垃圾箱/垃圾箱
如果[$#-ne 2];然后
回显用法:$0{string1}{string2}
E_BADARGS=65
退出$E_BADARGS
fi
找到-maxdepth 1-读取文件时为iname'*.r'|;做
awk“
开始{IGNORECASE=1;sawArg1=0;sawArg2=0}
/$1/{sawArg1=1}
/$2/{sawArg2=1}
sawArg1&&sawArg2{exit}#如果两行都匹配,则停止读取
结束{exit!(sawArg1和&sawArg2)}
" \
“${file}”\
&&ack--nofilter-H-i“$1 |$2”“${file}”
完成

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

非常感谢您提供解决方案。我可能在一个大目录上运行它,但任何解决方案都比没有解决方案好。我想我会把它另存为bash脚本,因为它会很方便。我想知道,是否可以使用--include in grep而不是在开始时运行find?如果我想调用它并将参数传递给
wordA
wordB
,我将如何修改此脚本。我想我必须做
“$1”
“$2”
,但它应该查找语法
wordA | wordB
?@Konrad我添加了将变量传递到shell脚本的示例代码。非常感谢,这是一个非常有用的工具。
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