g2'den satırların tam bloğunu (dosya1 içeriği) grep


9

İki dosyam var file1ve file2.

Örnek içeriği file1:

A B
C D
E F
G H

ve içeriği file2şöyle:

A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H

Bu yüzden tüm file1içerik bloğunu file2sadece aramak istiyorum . Bu, çıktının yalnızca şu satırları içermesi gerektiği anlamına gelir:

A B
C D
E F
G H

lütfen unutmayın: - sadece bir araya gelen çizgiler çıktının bir parçası olmalıdır.


Sorunu anlamadım. Yalnızca tam içeriğini yazdırmak file1ve başka bir şey yazdırmak istemiyorsanız kullanın cat file1.
Wildcard

@Wildcard, dosya2'nin dosya1 ile tam olarak aynı içeriği içerip içermediğini görmek istiyor. Bir kitapta belirli bir bölümü arıyormuş gibi düşünün
Sergiy Kolodyazhnyy

Ben "set üyeleri" önerilen yinelenen soruya kabul edilen cevap tarafından ele tek satır daha biraz daha karmaşık (ilk başta ben bunu fark etmedi) oluşur gibi yeniden açmak için oy.
Kusalananda

1
Bu setlerle ilgili değil . Bunu kopya olarak işaretlemek istiyorsanız, en azından çok satırlı normal ifadeler hakkında başka bir soru bulun.
Michael Vehrs

Yanıtlar:


11

grepçok satırlı kalıplar söz konusu olduğunda oldukça aptaldır, ancak \nkalıp ve metnin tüm yeni satır karakterlerini , \0karşılaştırılmadan önce NUL karakterlerine çevirmek bu sorunu çözer . \0Çıktıya geri çevirmenin \nde gerekli olduğu açıktır.

file1Arama yapmak istediğiniz kalıbı içerdiğini varsayarak komutunuz file2:

grep -aof <(tr '\n' '\0' < file1) <(tr '\n' '\0' < file2) | tr '\0' '\n'

Verilen dosyalarınız için örnek çıktı:

A B
C D
E F
G H

Açıklama:

  • <(tr '\n' '\0' < file1)eşittir file1, ancak tüm yeni satır karakterleri NUL karakterlerine çevrilmiş bir FIFO / adlandırılmış kanal / geçici dosya benzeri nesne oluşturur .
  • <(tr '\n' '\0' < file2)aynısını yapar, ama file2.
  • grep -f PATTERN_FILE INPUT_FILEdesenin (ler) için arama PATTERN_FILEolarak INPUT_FILE.
  • -aBayrağı grepikili dosyalar üzerinde eşleme. Aksi takdirde yazdırılamayan karakterler içeren dosyaları atlayacağından bu gereklidir \0.
  • -oBayrağı grepmarkaların sadece eşleştirme dizisi, değil bulunmuştur bütün çizgi yazdırmak.
  • | tr '\0' '\n' sol taraftaki komutun çıkışından tüm NUL karakterlerini yeni satır karakterlerine çevirir.

6

Aşağıdakiler beceriksizdir, ancak GNU ile çalışır awk:

awk -v RS="$(<file1)" '{print RT}' file2

3

Saf bash eğlencesi için

mapfile -t <file1
while read line ; do
    [ "$line" = "${MAPFILE[i++]}" ] || { ["$line" = "$MAPFILE" ] && i=1 || i=0; }
    [ $i -eq ${#MAPFILE[*]} ] && { printf "%s\n" "${MAPFILE[@]}"; i=0; }
done <file2

3

İşte biraz daha zarif grep+ perl:

$ grep -Pzo "$(perl -pe 's/\n/\\n/g' file1.txt )"  file2.txt                    
A B
C D
E F
G H

Ancak, büyük bir av var. Bir satırsonu varsa file1, desen başka bir deyişle, doğru olmayacaktır: A B\nC D\nE F\nG H\n\n.

(Perl parçasını sağladığınız için özel teşekkürler @terdon)

Kostaların belirttiği gibi, bir kişi perl -0pe 's/\n(\n+$)?/\\n/g' diğer perlkomutun yerine kullanılabilir.file1.txt


1
Sonunda bir satırsonu varsa ve bu OP değilse bulmak istiyorum perl -0pe 's/\n(\n+$)?/\\n/g'. Olmadan regex modificator ilave. -0g
Costas

1

Çıktının ne olmasını istediğinizden emin değilim, ancak özellikle satır yönelimli olmayan dillerle (özellikle her iki dosya da belleğe okunabiliyorsa) yapmak kolaydır. İşte size kaç tane eşleşme olduğunu söyleyecek bir python betiği.

import sys
find = open(sys.argv[1]).read()
hay = open(sys.argv[2]).read()
print("The text occurs", hay.count(find), "times")

Eşleştiği file1kadar çok yazdırmak ister misiniz ? Son satırı bununla değiştir:

print(find * hay.count(find))

Gerçekten istiyorsanız, her şeyi bir komut satırı çağrısına veya takma adına paketleyebilirsiniz:

python -c 'import sys; print("The text occurs", open(sys.argv[2]).read().count(open(sys.argv[1]).read()), "times")' file1 file2

1
grep -lir 'A B \n D C \n whatever' ./folder_to_search

sonuç tam metin eşleşmesine sahip tüm dosyalar olacaktır


0

İşte python kullanan başka bir yaklaşım ( python3 3.5.2hiçbir şikayeti olmadan test edildi pylint3 1.5.6):

""" Locate entire file contents contiguous in other file """

import sys
import re
from mmap import mmap, PROT_READ

def memmap(name):
    """ Return memoryview of readonly mmap """
    with open(name, 'rb') as file:
        return memoryview(mmap(file.fileno(), 0, access=PROT_READ))

def finder(needle, haystack):
    """ Return iterator """
    return re.compile(re.escape(needle)).finditer(haystack)

print(tuple(finder(*(memmap(name) for name in sys.argv[1:3]))))

Komut satırı argümanlarının ele alınması sys.argvkuşkusuz basittir. İçine geçtiğiniz finderiki memoryviewnesnenin dönüş değeriyle başka şeyler de yapabilirsiniz tuple. SRE_MatchYineleyici tarafından döndürülen her öğenin finder, bir örneği printçıktıda özetlenen çeşitli yöntemler vardır ( spanörneğin, her bir eşleşmenin bayt aralığını söyler).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.