grep для нескольких строк в файле на разных строках (т. е. весь файл, а не поиск по строке)? - PullRequest
78 голосов
/ 25 января 2011

Я хочу использовать grep для файлов, содержащих слова Dansk, Svenska или Norsk в любой строке, с пригодным для использования кодом возврата (поскольку мне действительно нравится иметь информацию о содержании строк, мойлайнер идет немного дальше, чем это).

У меня есть много файлов с такими строками:

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, 
(...)

Вот псевдокод того, что мне нужно:

Каков наилучший способ сделать это?Можно ли это сделать в одну строку?

Ответы [ 14 ]

1 голос
/ 27 октября 2011

Вот что хорошо сработало для меня:

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
1 голос
/ 25 января 2011

В ответ на awk @ kurumi, вот функция 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
0 голосов
/ 19 апреля 2016

У меня была эта проблема сегодня, и все однострочные здесь не удалось мне, потому что файлы содержали пробелы в именах.

Вот что я придумал, что сработало:

grep -ril <WORD1> | sed 's/.*/"&"/' | xargs grep -il <WORD2>
0 голосов
/ 16 июля 2013

Если вам нужны только два поисковых запроса, возможно, наиболее читаемый подход - запускать каждый поиск и пересекать результаты:

 comm -12 <(grep -rl word1 . | sort) <(grep -rl word2 . | sort)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...