【问题标题】:Find lines containing all keywords in bash script在 bash 脚本中查找包含所有关键字的行
【发布时间】:2019-04-14 17:37:18
【问题描述】:

基本上,我想要一些行为类似于:

cat file | grep -i keyword1 | grep -i keyword2 | grep -i keyword3

如何使用带有可变长度关键字参数列表的 bash 脚本来执行此操作?该脚本应该对包含所有关键字的行进行不区分大小写的匹配。

【问题讨论】:

  • 您是在问我们最好的方法是什么?
  • 是的。在采用可变数量关键字的 bash 脚本中,最优雅/最有效的方法是什么?

标签: bash grep


【解决方案1】:

将其用作脚本

#! /bin/bash awk -v IGNORECASE=1 -f <( P=; for k; do [ -z "$P" ] && P="/$k/" || P="$P&&/$k/"; done echo "$P{print}" )

并调用它

script.sh keyword1 keyword2 keyword3 &lt; file

【讨论】:

    【解决方案2】:

    我不知道这是否有效,我认为这很丑,也可能有一些实用程序,但是:

    #!/bin/bash
    
    unset keywords matchlist
    keywords=("$@")
    
    for kw in "${keywords[@]}"; do
    matchlist="$matchlist /$kw/ &&"
    done
    
    matchlist="${matchlist% &&}"
    
    # awk "$matchlist { print; }" < <(tr '[:upper:]' '[:lower:]' <file)
    awk "$matchlist { print; }" file
    

    是的,它需要一些关于特殊字符和东西的鲁棒性。只是为了展示这个想法。

    【讨论】:

    • 谢谢,这就是它的要点。但是如何使关键字匹配不区分大小写(如 grep -i)?
    • 你抓住了我!我认为 GNU awk 有类似 IGNORECASE 变量的东西,但我不确定。如果它是一个选项,您可以在读入时将输入文件小写并仅使用小写关键字:awk ...
    【解决方案3】:

    试试这个:

    shopt -s nocasematch
    keywords="keyword1|keyword2|keyword3"
    while read line; do [[ $line =~ $keywords ]] && echo $line; done < file
    

    编辑

    这是一个测试所有存在的关键字的版本,而不仅仅是任何关键字:

    keywords=(keyword1 keyword2 keyword3)    # or keywords=("$@")
    qty=${#keywords[@]}
    while read line
    do
        count=0
        for keyword in "${keywords[@]}"
        do
            [[ "$line" =~ $keyword ]] && (( count++ ))
        done
        if (( count == qty ))
        then
            echo $line
        fi
     done < textlines
    

    【讨论】:

    • 谢谢,我以前没用过shopt——学习新东西总是很好。这给出了不区分大小写的匹配,但它匹配包含任何关键字的行。我只想匹配包含所有关键字的行。
    【解决方案4】:

    找到了一种使用 grep 的方法。

    KEYWORDS=$@
    MATCH_EXPR="cat file"
    for keyword in ${KEYWORDS};
    do
      MATCH_EXPR="${MATCH_EXPR} | grep -i ${keyword}"
    done
    eval ${MATCH_EXPR}
    

    【讨论】:

      【解决方案5】:

      你可以使用 bash 4.0++

      shopt -s nocasematch
      while read -r line
      do
          case "$line" in 
              *keyword1*) f=1;;&
              *keyword2*) g=1;;&
              *keyword3*) 
                  [ "$f" -eq 1 ] && [ "$g" -eq 1 ] && echo $line;;
          esac
      done < "file"
      shopt -u nocasematch
      

      还是傻眼

      gawk '/keyword/&&/keyword2/&&/keyword3/' file
      

      【讨论】:

        【解决方案6】:

        我会在 Perl 中完成。

        用于查找至少包含其中之一的所有行:

        perl -ne'print if /(keyword1|keyword2|keyword3)/i' file
        

        用于查找包含所有这些行的所有行:

        perl -ne'print if /keyword1/i && /keyword2/i && /keyword3/i' file
        

        【讨论】:

          【解决方案7】:

          这是一个在 bash 中名为 search.sh 的脚本,它将在文件或文件夹中的行中搜索所有指定的关键字:

          #!/bin/bash
          if [ $# -lt 2 ]; then
              echo "[-] $0 file_to_search/folder_to_search keyword1 keyword2 keyword3 ..."
              exit
          fi
          all_args="$@"
          i=0
          results=""  # this will store the cumulative results from each keyword search
          for arg in $all_args; do
              if [ $i -eq 0 ]; then
                  # first argument is the file/folder to search
                  file_to_search="$arg"
                  i=$(($i + 1))
              elif [ $i -eq 1 ]; then
                  # search the file/folder with first keyword (first search)
                  results=`grep --color=always -r -n -i "$arg" "$file_to_search"`
                  i=$(($i + 1))
              else
                  # now keep searching the results from first search for other keywords
                  results=`echo "$results" | grep --color=always -i "$arg"`
                  i=$(($i + 1))
              fi
          done
          echo "$results"
          

          上述脚本调用示例将在“tools.txt”文件中搜索“python”和“jira”关键字:

          ./search.sh tools.txt python jira
          

          【讨论】:

            猜你喜欢
            • 2014-09-04
            • 2015-06-08
            • 2020-01-07
            • 1970-01-01
            • 2018-01-26
            • 1970-01-01
            • 1970-01-01
            • 2018-02-24
            • 2013-05-13
            相关资源
            最近更新 更多