it-swarm-vi.tech

grep cho nhiều chuỗi trong tệp trên các dòng khác nhau (ví dụ: toàn bộ tệp, không phải tìm kiếm dựa trên dòng)?

Tôi muốn grep cho các tệp có chứa các từ Dansk, Svenska hoặc Norsk trên bất kỳ dòng nào, với một mã trả về có thể sử dụng được (vì tôi thực sự chỉ muốn có thông tin rằng các chuỗi được chứa, một dòng của tôi sẽ đi xa hơn một chút sau đó).

Tôi có nhiều tệp có dòng trong đó như thế này:

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

Đây là mã giả của những gì tôi muốn:

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

Cách tốt nhất để làm việc này là gì? Nó có thể được thực hiện trên một dòng?

76
Christian

Bạn có thể dùng: 

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

Nếu bạn cũng muốn tìm trong các tập tin ẩn:

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

Một cách khác chỉ sử dụng bash và grep:

Đối với một tệp 'test.txt':

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

Sẽ in test.txt nếu tệp chứa cả ba (trong mọi kết hợp). Hai greps đầu tiên không in bất cứ thứ gì (-q) và cuối cùng chỉ in tệp nếu hai cái kia đã qua.

Nếu bạn muốn làm điều đó cho mọi tệp trong thư mục:

 cho f trong *; làm grep -q Dansk $ f && grep -q Norsk $ f && grep -l Svenska $ f; làm xong
21
Edd Steel
grep –irl Word1 * | grep –il Word2 `cat -` | grep –il Word3 `cat -`
  • -i làm cho trường hợp tìm kiếm không nhạy cảm
  • -r làm cho tìm kiếm tệp đệ quy thông qua các thư mục
  • -l liệt kê danh sách các tệp có Word được tìm thấy
  • cat - khiến grep tiếp theo xem qua các tệp được truyền vào danh sách đó.
12
Gerry

Cách grep cho nhiều chuỗi trong tệp trên các dòng khác nhau (Sử dụng ký hiệu ống):

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

Ghi chú:

  1. Nếu bạn sử dụng dấu ngoặc kép "" với grep của mình, bạn sẽ phải thoát khỏi đường ống như thế này: \| để tìm kiếm Dansk, Norsk và Svenska.

  2. Giả sử rằng một dòng chỉ có một ngôn ngữ.

Hướng dẫn: http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/

9
Damodharan R

Bạn có thể làm điều này thực sự dễ dàng với ack :

ack -l 'cats' | ack -xl 'dogs'
  • -l: trả về danh sách các tệp 
  • -x: lấy các tệp từ STDIN (tìm kiếm trước đó) và chỉ tìm kiếm các tệp đó

Và bạn chỉ có thể tiếp tục đường ống cho đến khi bạn nhận được các tập tin bạn muốn.

5
Ben Johnson

Điều này tìm kiếm nhiều từ trong nhiều tệp:

egrep 'abc|xyz' file1 file2 ..filen 
5
Sarath Chandra
awk '/Dansk/{a=1}/Norsk/{b=1}/Svenska/{c=1}END{ if (a && b && c) print "0" }' 

sau đó bạn có thể bắt giá trị trả về với Shell

nếu bạn có Ruby (1.9+)

Ruby -0777 -ne 'print if /Dansk/ and /Norsk/ and /Svenka/' file
4
kurumi

Đơn giản:

grep 'Word1\|Word2\|Word3' *

xem bài đăng này để biết thêm

3
moshe beeri

Đây là sự pha trộn giữa câu trả lời của glenn jackman và Kurumi, cho phép số lượng các biểu thức tùy ý thay vì một số lượng từ cố định hoặc một bộ các biểu thức cố định.

#!/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
    }
}

Chạy nó như thế này:

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

Mở rộng câu trả lời awk của @ Kurumi, đây là một hàm 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
        }
    ' "[email protected]"
    return $?
}

Sử dụng:

if all_Word_search Dansk Norsk Svenska filename; then
    echo "all words found"
else
    echo "not all words found"
fi
1
glenn jackman

Đây là những gì làm việc tốt cho tôi:

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

Nếu tôi chỉ muốn tìm các tệp .sh với ba tệp này, thì tôi có thể đã sử dụng:

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
Nick Henry

Tôi đã làm điều đó với hai bước. Tạo một danh sách các tệp csv trong một tệp Với sự giúp đỡ của các nhận xét trang này, tôi đã thực hiện hai bước không có kịch bản để có được những gì tôi cần. Chỉ cần gõ vào thiết bị đầu cuối:

$ 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`

nó đã làm chính xác những gì tôi cần - in tên tệp chứa cả ba từ. 

Cũng lưu ý các ký hiệu như `' "

1
Simas

Tôi đã gặp vấn đề này ngày hôm nay và tất cả các lớp lót ở đây đều thất bại với tôi vì các tệp chứa khoảng trắng trong tên.

Đây là những gì tôi đã đưa ra mà làm việc:

grep -ril <Word1> | sed 's/.*/"&"/' | xargs grep -il <Word2>
0
giusti

Nếu bạn chỉ cần hai thuật ngữ tìm kiếm, có thể cho rằng cách tiếp cận dễ đọc nhất là chạy từng tìm kiếm và giao kết quả:

 comm -12 <(grep -rl Word1 . | sort) <(grep -rl Word2 . | sort)
0
Ankur Dave