Mam ten plik:
sometext1{
string1
}
sometext2{
string2
string3
}
sometext3{
string4
string5
string6
}
Chcę przeszukać ten plik pod kątem określonego ciągu i wydrukować wszystko przed tym ciągiem aż do otwarcia {
i wszystko po tym ciągu aż do zamknięcia }
. Próbowałem to osiągnąć za pomocą sed, ale jeśli spróbuję wydrukować wszystko w zakresie, /{/,/string2/
na przykład sed wydrukuje to:
sometext1{
string1
}
sometext2{
string2
sometext3{
string4
string5
string6
}
Jeśli szukam ciągu „string2”, potrzebuję danych wyjściowych:
sometext2{
string2
string3
}
Dzięki.
text-processing
sed
rodrigo
źródło
źródło
grep -n '' <infile | sed ...
. Tesed
komendy będą musiały modyfikującego; w szczególności bity/
adresu,/
które szukają^
najlepszych kotwic. Tak więc, jeśli były przy użyciu moją odpowiedź prawdopodobnie można zrobić:grep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d'
. Wszystkie wiersze wyjściowe będą poprzedzone numerami wierszy w oryginalnym pliku, a następnie dwukropkiem itp1:sometext1{\n2:string1
.sed
będzie filtrować tylko to, co wcześniej filtrował, z wyjątkiem tego, że każda linia wyjściowa otwiera się liczbą.Odpowiedzi:
Oto dwa polecenia. Jeśli potrzebujesz polecenia, które przycina do ostatniego
.*{$
wiersza w sekwencji (jak robi to @don_crisstied
) , możesz:... która polega na dodawaniu każdej linii do
H
starej spacji po\n
znaku ewline, zastępowaniuh
starej spacji dla każdej pasującej linii{$
oraz zamianieh
starych i wzorów spacji dla każdej pasującej linii^}
- a tym samym opróżnieniu bufora.Drukuje tylko linie, które pasują
{
wtedy do\n
ewline, a następniePATTERN
w pewnym momencie - i to dzieje się tylko natychmiast po zamianie bufora.Przesuwa wszystkie wiersze w serii
{$
dopasowań do ostatniego w sekwencji, ale możesz uzyskać wszystkie z nich, takie jak:To, co robi, to zamień wzór i
h
stare spacje dla każdej...{$.*^}.*
sekwencji, dołącza wszystkie linie w sekwencji doH
starej spacji po\n
znakuD
ewline i usuwa do pierwszego występującego\n
znaku ewline w przestrzeni wzorów dla każdego cyklu linii, zanim zacznie ponownie od tego, co pozostało.Oczywiście, jedyny raz, kiedy dostaje
\n
ewline w przestrzeni wzorca, to kiedy linia wejściowa jest zgodna^}
- koniec zakresu - a więc kiedy ponownie uruchamia skrypt przy każdej innej okazji, zwyczajnie wciąga kolejną linię wejściową.Kiedy
PATTERN
znajduje się w tej samej przestrzeni wzorca jako\n
ewline jednak, że drukuje dużo przed zastąpieniem go^}
ponownie (tak może skończyć zakres i opróżnić bufor) .Biorąc pod uwagę ten plik wejściowy (dzięki don) :
Pierwsze odbitki:
...i drugi...
źródło
}
. Może to być korzystne dla ...open{\nsub;\n{ command; }\n}; close
- ale nie jestem pewien, o co tu chodzi ...{...}
blokach? Jeśli tak jest i korzystasz z pierwszego rozwiązania, możesz zrobić to/{$/,/^}/H
na początku zamiast po prostuH
. Ale jeśli wypróbowałeś także drugie rozwiązanie i nadal napotkałeś ten sam błąd, prawdopodobnie nie pomoże, ponieważ już to robi. I też nie dyskontujed
. don ma tutaj bardzo dobrą odpowiedź ied
można go również bardzo łatwo zastosować do tymczasowych plików bufora , co powinno zapobiec przepełnieniu bufora pamięci.Oto rozwiązanie z
ed
:to jest:
Zakłada się, że
PATTERN
pomiędzy każdą parą jest tylko jedna linia, w{
}
przeciwnym razie otrzymasz duplikat danych wyjściowych dla każdej dodatkowej linii zPATTERN
tym samym blokiem.Będzie działał dla wielu
{
}
zawierających dopasowanie do jednej linii,PATTERN
np. Dla pliku testowego zPATTERN
dwiema różnymi sekcjami:bieganie
wyjścia:
źródło
Z
pcregrep
:Lub z GNU
grep
pod warunkiem, że dane wejściowe nie zawierają NUL bajtów:źródło
gdzie:
string4
-> ciąg znaków do dopasowaniat1.txt
-> zawiera treść pliku wymienioną w zapytaniuźródło
nazwa pliku sed -n '/ string / p'
-n po dodaniu do domyślnego zachowania sed tłumi sed, instrukcja ta może nie dać ci dokładnie tego, czego chcesz, ale powinna po prostu przesunąć ciąg
źródło