如何使用grep来匹配同一行中的多个string?

我正在尝试使用grep来匹配包含两个不同string的行。 我已经尝试了以下,但这匹配包含string1 string2这不是我想要的行。

 grep 'string1\|string2' filename 

那么我怎样才能和grep匹配只包含两个string的行呢?

你可以使用grep 'string1' filename | grep 'string2' grep 'string1' filename | grep 'string2'

或者, grep 'string1.*string2\|string2.*string1' filename

我想这就是你要找的东西:

 grep -E "string1|string2" filename 

我认为这样的答案:

 grep 'string1.*string2\|string2.*string1' filename 

只能匹配两者都存在的情况,而不是一个或另一个或两者。

只要给它多个-e选项。

  -e pattern, --regexp=pattern Specify a pattern used during the search of the input: an input line is selected if it matches any of the specified patterns. This option is most useful when multiple -e options are used to specify multiple patterns, or when a pattern begins with a dash (`-'). 

因此命令变成:

 grep -e "string1" -e "string2" filename 

注意:上面我引用了BSD版本的手册,但看起来在Linux上是一样的 。

search包含任何地方的任何顺序的所有单词的文件:

 grep -ril \'action\' | xargs grep -il \'model\' | xargs grep -il \'view_type\' 

第一个grep启动一个recursionsearch( r ),忽略大小写( i )并列出(打印出)与( l )匹配的文件的名字(单引号中的'action' )文件。

随后的grepssearch其他术语,保持不区分大小写并列出匹配的文件。

您将得到的文件的最终列表将包含这些条款,在文件中的任何位置的任何顺序。

如果你有一个perl正则expression式的-P选项的grep ,你可以使用

 grep -P '(?=.*string1)(?=.*string2)' 

它具有处理重叠string的优点。 使用perl作为grep更简单一些,因为你可以直接指定和逻辑:

 perl -ne 'print if /string1/ && /string2/' 

你的方法几乎是好的,只是错过了-w

 grep -w 'string1\|string2' filename 

你可以尝试这样的事情:

 (pattern1.*pattern2|pattern2.*pattern1) 

| 在正则expression式中的运算符意味着或。 也就是说string1或者string2都会匹配。 你可以这样做:

 grep 'string1' filename | grep 'string2' 

这将把第一个命令的结果传递给第二个grep。 这应该只给你两条线匹配。

发现只有6个空格开始的行,并完成:

  cat my_file.txt | grep -e '^ .*(\.c$|\.cpp$|\.h$|\.log$|\.out$)' # .c or .cpp or .h or .log or .out -e '^ .*[0-9]\{5,9\}$' # numers between 5 and 9 digist > nolog.txt 

多线匹配:

 echo -e "test1\ntest2\ntest3" |tr -d '\n' |grep "test1.*test3" 

要么

 echo -e "test1\ntest5\ntest3" >tst.txt cat tst.txt |tr -d '\n' |grep "test1.*test3\|test3.*test1" 

我们只需要删除换行符就行了!

你应该有这样的grep

 $ grep 'string1' file | grep 'string2' 

将要grep的string放入文件中

 echo who > find.txt echo Roger >> find.txt echo [44][0-9]{9,} >> find.txt 

然后使用-fsearch

 grep -f find.txt BIG_FILE_TO_SEARCH.txt 
 grep '(string1.*string2 | string2.*string1)' filename 

将以任何顺序获得与string1和string2的行

我经常碰到和你一样的问题,我只写了一段脚本:

 function m() { # m means 'multi pattern grep' function _usage() { echo "usage: COMMAND [-inH] -p<pattern1> -p<pattern2> <filename>" echo "-i : ignore case" echo "-n : show line number" echo "-H : show filename" echo "-h : show header" echo "-p : specify pattern" } declare -a patterns # it is important to declare OPTIND as local local ignorecase_flag filename linum header_flag colon result OPTIND while getopts "iHhnp:" opt; do case $opt in i) ignorecase_flag=true ;; H) filename="FILENAME," ;; n) linum="NR," ;; p) patterns+=( "$OPTARG" ) ;; h) header_flag=true ;; \?) _usage return ;; esac done if [[ -n $filename || -n $linum ]]; then colon="\":\"," fi shift $(( $OPTIND - 1 )) if [[ $ignorecase_flag == true ]]; then for s in "${patterns[@]}"; do result+=" && s~/${s,,}/" done result=${result# && } result="{s=tolower(\$0)} $result" else for s in "${patterns[@]}"; do result="$result && /$s/" done result=${result# && } fi result+=" { print "$filename$linum$colon"\$0 }" if [[ ! -t 0 ]]; then # pipe case cat - | awk "${result}" else for f in "$@"; do [[ $header_flag == true ]] && echo "########## $f ##########" awk "${result}" $f done fi } 

用法:

 echo "abc" | m -p A echo "abc" | m -i -p A # abc 

如果你喜欢,你可以把它放在.bashrc中。

假设我们需要在文件testing文件中find多个单词的计数。 有两种方法可以解决这个问题

1)使用正则expression式匹配模式的grep命令

 grep -c '\<\(DOG\|CAT\)\>' testfile 

2)使用egrep命令

 egrep -c 'DOG|CAT' testfile 

使用egrep,您不必担心expression式,只需通过pipe道分隔符分隔单词。

正如人们提出的perl和python以及令人费解的shell脚本一样,这里有一个简单的awk方法:

 awk '/string1/ && /string2/' filename 

看了看所接受的答案的评论:不,这不是多行的; 但那也不是问题的作者所要求的。