grep在不同行的文件中的多个字符串(即整个文件,而不是基于行的搜索)?

时间:2011-01-25 15:28:36

标签: bash awk grep

我想在任何一行上grep包含单词DanskSvenskaNorsk的文件,并使用可用的返回码(因为我真的只想获得字符串的信息包含在内,我的单行程比这更进一步。)

我有许多带有行的文件,如下所示:

Disc Title: unknown
Title: 01, Length: 01:33:37.000 Chapters: 33, Cells: 31, Audio streams: 04, Subpictures: 20
        Subtitle: 01, Language: ar - Arabic, Content: Undefined, Stream id: 0x20, 
        Subtitle: 02, Language: bg - Bulgarian, Content: Undefined, Stream id: 0x21, 
        Subtitle: 03, Language: cs - Czech, Content: Undefined, Stream id: 0x22, 
        Subtitle: 04, Language: da - Dansk, Content: Undefined, Stream id: 0x23, 
        Subtitle: 05, Language: de - Deutsch, Content: Undefined, Stream id: 0x24, 
(...)

这是我想要的伪代码:

for all files in directory;
 if file contains "Dansk" AND "Norsk" AND "Svenska" then
 then echo the filename
end

最好的方法是什么?可以在一条线上完成吗?

16 个答案:

答案 0 :(得分:81)

您可以使用:

grep -l Dansk * | xargs grep -l Norsk | xargs grep -l Svenska

如果您还想在隐藏文件中找到:

grep -l Dansk .* | xargs grep -l Norsk | xargs grep -l Svenska

答案 1 :(得分:21)

另一种使用bash和grep的方式:

对于单个文件'test.txt':

  grep -q Dansk test.txt && grep -q Norsk test.txt && grep -l Svenska test.txt

如果文件包含全部三个(以任意组合),将打印test.txt。前两个greps不打印任何内容(-q),最后一个只打印文件,如果其他两个已经过了。

如果要对目录中的每个文件执行此操作:

   for f in *; do grep -q Dansk $f && grep -q Norsk $f && grep -l Svenska $f; done

答案 2 :(得分:15)

grep –irl word1 * | grep –il word2 `cat -` | grep –il word3 `cat -`
  • -i使搜索不区分大小写
  • -r通过文件夹递归文件搜索
  • -l使用找到的单词管理文件列表
  • cat -会导致下一个grep查看传递给它的文件列表。

答案 3 :(得分:10)

如何在不同行的文件中grep多个字符串(使用管道符号):

for file in *;do 
   test $(grep -E 'Dansk|Norsk|Svenska' $file | wc -l) -ge 3 && echo $file
done

注意:

  1. 如果您在grep中使用双引号"",则必须按照以下方式转义管道:\|以搜索Dansk,Norsk和Svenska。

  2. 假设一行只有一种语言。

  3. 演练:http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/

答案 4 :(得分:6)

这会搜索多个文件中的多个单词:

egrep 'abc|xyz' file1 file2 ..filen 

答案 5 :(得分:5)

您可以使用ack

轻松完成此操作
ack -l 'cats' | ack -xl 'dogs'
  • -l:返回文件列表
  • -x:从STDIN获取文件(上一次搜索)并仅搜索这些文件

你可以保持管道直到你得到你想要的文件。

答案 6 :(得分:4)

awk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print "0" }' 

然后您可以使用shell

捕获返回值

如果你有Ruby(1.9 +)

ruby -0777 -ne 'print if /Dansk/ and /Norsk/ and /Svenka/' file

答案 7 :(得分:3)

简单地:

grep 'word1\|word2\|word3' *

请参阅this post了解详情

答案 8 :(得分:2)

这是glenn jackman和kurumi的答案的混合,它允许任意数量的正则表达式而不是任意数量的固定单词或一组固定的正则表达式。

#!/usr/bin/awk -f
# by Dennis Williamson - 2011-01-25

BEGIN {
    for (i=ARGC-2; i>=1; i--) {
        patterns[ARGV[i]] = 0;
        delete ARGV[i];
    }
}

{
    for (p in patterns)
        if ($0 ~ p)
            matches[p] = 1
            # print    # the matching line could be printed
}

END {
    for (p in patterns) {
        if (matches[p] != 1)
            exit 1
    }
}

像这样运行:

./multigrep.awk Dansk Norsk Svenska 'Language: .. - A.*c' dvdfile.dat

答案 9 :(得分:1)

扩展@ kurumi的awk答案,这是一个bash函数:

all_word_search() {
    gawk '
        BEGIN {
            for (i=ARGC-2; i>=1; i--) {
                search_terms[ARGV[i]] = 0;
                ARGV[i] = ARGV[i+1];
                delete ARGV[i+1];
            }
        }
        {
            for (i=1;i<=NF; i++) 
                if ($i in search_terms) 
                    search_terms[$1] = 1
        }
        END {
            for (word in search_terms) 
                if (search_terms[word] == 0) 
                    exit 1
        }
    ' "$@"
    return $?
}

用法:

if all_word_search Dansk Norsk Svenska filename; then
    echo "all words found"
else
    echo "not all words found"
fi

答案 10 :(得分:1)

这对我来说效果很好:

find . -path '*/.svn' -prune -o -type f -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \;
./path/to/file1.sh
./another/path/to/file2.txt
./blah/foo.php

如果我只想找到这三个的.sh文件,那么我可以使用:

find . -path '*/.svn' -prune -o -type f -name "*.sh" -exec gawk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print FILENAME }' {} \;
./path/to/file1.sh

答案 11 :(得分:1)

我通过两个步骤做到了这一点。在一个文件中列出csv文件 在本页评论的帮助下,我做了两个无脚本的步骤来获得我需要的东西。只需键入终端:

$ find /csv/file/dir -name '*.csv' > csv_list.txt
$ grep -q Svenska `cat csv_list.txt` && grep -q Norsk `cat csv_list.txt` && grep -l Dansk `cat csv_list.txt`

它完全符合我的需要 - 打印包含所有三个单词的文件名。

还要注意像`' "

这样的符号

答案 12 :(得分:0)

如果您只需要两个搜索词,可以说最可读的方法是运行每个搜索并与结果相交:

 comm -12 <(grep -rl word1 . | sort) <(grep -rl word2 . | sort)

答案 13 :(得分:0)

今天我遇到了这个问题,而且这里的所有单行都没有找到我,因为文件名称中包含空格。

这就是我提出的有效方法:

grep -ril <WORD1> | sed 's/.*/"&"/' | xargs grep -il <WORD2>

答案 14 :(得分:0)

如果您已安装git

git grep -l --all-match --no-index -e Dansk -e Norsk -e Svenska

--no-index搜索当前目录中不受Git管理的文件。因此,此命令将在任何目录中运行,无论它是否是git存储库。

答案 15 :(得分:0)

bash 中用于文件 LIST 的任意列表 my_file.txt 的简单单行代码可以是:

LIST="Dansk Norsk Svenska"
EVAL=$(echo "$LIST" | sed 's/[^ ]* */grep -q & my_file.txt \&\& /g'); eval "$EVAL echo yes || echo no"

eval 替换为 echo 显示,会评估以下命令:

grep -q Dansk  my_file.txt && grep -q Norsk  my_file.txt && grep -q Svenska my_file.txt &&  echo yes || echo no