Chciałbym wyszukać tekst, który może być podzielony na kilka wierszy w pliku. Grep, który zignoruje podział linii i zwróci pasujący zakres linii.
np. szukałbym is an example file
i oczekuję, że znajdzie się w następującym pliku:
To przykładowy plik.
Nie polegać na wiodących lub końcowych spacjach, najlepiej całkowicie ignorować wszystkie formy białej przestrzeni (najlepiej traktując dowolną sekwencję białej przestrzeni jako pojedynczą spację).
Jednym nieidealnym rozwiązaniem jest tr '\n' ' ' | grep
rozróżnienie między dopasowaniami a niepasującymi, ale nie pokazuje dopasowania ani nie radzi sobie dobrze z dużymi plikami.
text-processing
grep
search
newlines
Nikana Reklawyks
źródło
źródło
isearch-forward
)/This\_sis
. Aby uzyskać więcej informacji::help \_s
.Odpowiedzi:
GNU
grep
może to zrobićAby spełnić niektóre punkty, które pojawiają się w komentarzach, istnieją pewne modyfikacje skryptu:
Jeśli chodzi o ogromne pliki, nie wyobrażam sobie ograniczenia pamięci, ale w przypadku problemu możesz swobodnie korzystać
sed
które przechowują w pamięci nie więcej niż 4 wiersze (ponieważ 4 słowa we wzorach
\(\n.*\)\{3\}
).źródło
-z
opcja mówi,grep
aby traktować znaki nowej linii jak zwykłe znaki tekstowe i szukać nul bajtów do oddzielania rekordów. W pliku tekstowym bez bajtów zerowych (tj. W typowym przypadku)grep -z
potraktuje cały plik jako jedną linię. Tak więc (1) rodzi się pytanie, jak dobrze radzi sobie z dużymi plikami, i (2) jeśli znajdzie dopasowanie, wypisze cały plik, nie dając pojęcia o lokalizacji dopasowania. Również (3) OP powiedział: „idealnie, traktując dowolną sekwencję białych spacji jako pojedynczą spację”, więc powinieneś użyć\s+
i dodać-E
.-o
,; Ciągle o tym zapominam. Sprytny sposób z niego korzystać. (1) Twoja nowagrep
odpowiedź zaczyna się^[\n]*
; to literówka[^\n]*
. (2) powiedziałem\s+
celowo.be\s*little
będzie pasowaćbelittle
icare\s*less
będzie pasowaćcareless
. Ale to chyba drobny problem. A jeśli nie chcesz używać-E
, możesz użyć „wersji biedaka”\s+
, a mianowicie\s\s*
. (3) Ładnesed
polecenie. Może się nie powieść, jeśli są puste linie (tak, aby czterosłowowa fraza mogła rozciągać się na więcej niż cztery linie); Mogłem to naprawić, dodającs/\n\s*\n/\n/
.-E
ciebie stali w stanie wykorzystać+
w\s\+
formie. Puste linie wewnątrz wzoru wydają się być wymyślone.grep
nich wyrażeń.Spróbuj tego:
źródło
\s
5 razy, jeśli szukam „to bardzo długi wzór”?\s
odpowiada spacjom, a nowa linia to „spacja”.This\nis a very\nlong pattern
i nie wiem, gdzie mogą wystąpić podziały linii. Musiałbym szukaćThis\sis\sa\svery\slong\spattern
, prawda? (co staje się nużące wraz ze wzrostem długości wzoru lub wklejeniem go z innego miejsca)pcregrep -M "$( echo 'This is a very long pattern' | sed 's/ /\\s+/g' )" file
.