Odczytywanie wzorów grep z pliku

49

Mam kilka dużych plików tekstowych, aw pliku UNIQS.txtmam listę ciągów znaków grepz innego pliku. Kod, którego używam to

grep -f UNIQS.txt EEP_VSL.uniqs.sam > UNIQ_templates.sam

który nic nie robi - wygenerowany plik jest pusty. Ale kiedy robię

grep -F -f UNIQS.txt EEP_VSL.uniqs.sam > UNIQ_templates.sam

działa poprawnie. Wprawia mnie to w zakłopotanie, ponieważ nie sądziłem, grepże zinterpretuję te wpisy UNIQS.txtjako wzorce wyrażeń regularnych bez cudzysłowów i ukośników itd. W pliku (którego nie ma). Czy ogólnie jest tak, że jeśli pobierasz wzorce z pliku, automatycznie pomyśli, że są wzorcami regularnymi?

Edycja: W UNIQS.txtpliku znajdują się ciągi oddzielone znakiem nowej linii

HWI-ST365:215:D0GH0ACXX:2:1101:10034:186783

(zwane nazwami szablonów) i EEP_VSL...kolumnami pliku oddzielonymi kartami, z około 14 kolumnami, a pierwsza kolumna to nazwa szablonu, więc w zasadzie chcę wyodrębnić linię odpowiadającą każdemu szablonowi w pliku.

sdf
źródło

Odpowiedzi:

60

-fOpcja określa plik gdzie grep czyta wzory. To tak jak przekazywanie wzorców w wierszu poleceń (z -eopcją, jeśli istnieje więcej niż jeden), z tym wyjątkiem, że gdy dzwonisz z powłoki, możesz potrzebować zacytować wzór, aby chronić znaki specjalne w nim przed rozwinięciem przez powłokę.

Argument -Elub -Flub -P, jeśli w ogóle, mówi grep których składnia wzory są zapisywane w Bez argumentu grep spodziewa. Podstawowych wyrażeń regularnych ; z -E, grep oczekuje rozszerzonych wyrażeń regularnych ; z -P(jeśli obsługiwane), grep oczekuje wyrażeń regularnych Perla ; i z -F, grep oczekuje dosłownych ciągów znaków. Nie ma znaczenia, czy wzorce pochodzą z wiersza poleceń, czy z pliku.

Zauważ, że ciągi są podciągami: jeśli przejdziesz a+bjako wzór, a+b+cdopasowana zostanie linia zawierająca . Jeśli chcesz wyszukać wiersze zawierające dokładnie jeden z dostarczonych ciągów i nie więcej, przekaż tę -xopcję.

Gilles „SO- przestań być zły”
źródło
1
Ok, to się przydaje dzięki. Czy mogę zapytać, załóżmy, że chciałem dokładnie dopasować ciąg, tzn. Jeśli ciąg ma wartość 12345, chcę, aby pasował tylko do 12345, a nie do 123456 lub 123455 itd., Jak bym to zrobił?
sdf
2
@sdf Przeczytaj mój ostatni akapit:-x
Gilles 'SO- przestań być zły'
To jest tak stare, przepraszam za wykopanie go. Chociaż powyższe wyjaśnienie jest niesamowite, nieco niejasne jest, dlaczego wzorce (ciągi) z pliku nie pasują bez -Fflagi. Domyślam się, -że powyższy wiersz próbki powoduje, że jest to odczytywane jako ciąg znaków? Czy nie wymagałoby to również nawiasów kwadratowych? Testowałem z niektórymi przykładowymi plikami, ale nie doszedłem do wniosku.
trs
@trs Linia pokazana w pytaniu (które zostało dodane po opublikowaniu mojej odpowiedzi) nie zawiera żadnego znaku, który ma specjalne znaczenie w wyrażeniach regularnych, więc zachowuje się tak samo zi bez -F. Zrobiłoby to różnicę w przypadku postaci takich jak \[*^$.
Gilles „SO- przestań być zły”
@Gilles dzięki, to też było moje wrażenie, ale @sdf twierdzi, że „wygenerowany plik jest pusty” (odczyt: brak dopasowań) bez -Fflagi?
trs
0

Miałem ten sam błąd, który nie został rozwiązany dzięki dobrej odpowiedzi z @ gilles. Przyglądając się bliżej w pliku wejściowym, na końcu znalazłem 2 znaki nowej linii. Bez nich sukces wymagałby tylko: grep -i file_pattern_input plik

(GNU grep 3.1, plik wejściowy ponad 5000 rekordów, plik dopasowania / wzorca 2536, wiedziałem, że wszystkie 2536 muszą znajdować się w pliku. Dzięki nowym wierszom wszystkie linie pliku i tylko 2536 pasujących linii)

dzięki
źródło
1
Nie ma to związku z problemem OP. Pusta linia jest odczytywana przez grep jako pusty wzór, a pusty wzór pasuje wszędzie.
muru