Użyj listy słów, aby grep na innej liście


8

Mam listę z 250 liniami. Muszę uruchomić je wszystkie przez serwer WWW, aby uzyskać listę wyników. Ta lista zwraca jednak o wiele więcej wierszy, niż jestem zainteresowany. Powiedzmy, że moje list.txtto:

a.1
b.1
etc

następnie dane wyjściowe to output.txt:

a.1 a b c
a.2 b a b
a.3 d k o
b.1 b o p
b.2 o i y
b.3 p i y
etc

Czy można użyć polecenia grep, aby wyszukać wszystkie słowa w list.txt w pliku output.txt, a następnie wygenerować listę „Wanted” Want.txt? Potrzebuję całego wiersza w moim pliku wyjściowym. Txt Jestem nowy w skryptach, ale chciałbym coś takiego

grep list.txt output.txt > wanted.txt

Nie znalazłem żadnych przykładów tego


Czy oba są w kolejności alfabetycznej jak twoje przykłady?
Oli

Nie, mam określoną kolejność niealfabetyczną na liście.txt, ale plik output.txt jest alfabetyczny, ale chciałbym, aby zawierał tylko „trafienia” dla mojej listy.txt w tej samej kolejności niealfabetycznej
Ditte

Odpowiedzi:


11

Zignorowałbym grepten. Jest dobry do wyrażeń regularnych, ale nie wygląda na to, że naprawdę potrzebujesz go tutaj. commmoże porównać dwa pliki i pokazać skrzyżowania. Korzystając z dokładnych przykładów:

$ comm -12 list.txt output.txt 
a.1
b.1
etc

Jest to szybsze niż jakikolwiek grep, ale zależy (w dużym stopniu) od sortowanych plików. Jeśli nie są, możesz je wstępnie posortować, ale to zmieni dane wyjściowe, więc również zostanie posortowane.

comm -12 <(sort list.txt) <(sort output.txt) 

Alternatywnie, ta odpowiedź od iiSeymour pozwoli ci to zrobić grep. Flagi proszą o plik wejściowy i wymuszają wyszukiwanie ciągów pełnych słów. To nie będzie zależało od zamówienia, ale będzie oparte na output.txtzamówieniu. Odwróć pliki, jeśli chcesz je w kolejności list.txt.

$ grep -wFf list.txt output.txt 
a.1
b.1
etc

Jeśli twój list.txtjest naprawdę duży, być może będziesz musiał poradzić sobie z tym trochę iteracyjnie i przekazać każdą linię osobno. To znacznie wydłuży czas przetwarzania. W powyższym output.txtczytałbyś raz, ale w ten sposób czytałeś i przetwarzałeś go dla każdej linii list.txt. To okropne ... Ale to może być twój jedyny wybór. Z drugiej strony sortuje rzeczy według list.txtkolejności.

$ while read line; do grep -wF "$line" output.txt; done < list.txt
a.1
b.1
etc

1
To jest naprawdę mądre! Jaki jest powód -12?
Ditte

3
-1pomija wiersze unikalne dla pierwszego pliku, -2pomija wiersze unikalne dla drugiego pliku i -3pomija wiersze wspólne dla obu plików . Aby uzyskać tylko wspólne linie, tłumimy unikalne, stąd -12.
Oli

miły! Myślę, że użyję komendy comm. A kiedy chcę posortować plik output.txt, aby mieć taką samą kolejność jak list.txt, użyję po prostu comm -12 <(sort list.txt) <(sort output.txt)?
Ditte

Komenda comm nie dała mi całej linii w wynikach.txt (i potrzebuję tego wszystkiego, aby uzyskać stamtąd informacje). Ale jeśli spróbuję polecenia grep, to daje mi grep: brak pamięci. Czy to znaczy, że jest za duży?
Ditte

drugi przykład zawiera redundantne przekierowanie STDIN, powłoka oznaczałaby jako błąd. albo stwórz pliki tymczasowe, albo użyj dodatkowego fd z potokowym sortowaniem w tle (trudne w większości powłok) ... to bardziej pytanie programistyczne, które lepiej zadać w przypadku przepełnienia stosu . osobiście zrobiłbym to w Pythonie.
Skaperen
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.