Zamierzam przesłać formularz za pomocą cURL, gdzie część zawartości pochodzi z innego pliku, wybranego za pomocą sed
Jeśli param1
używa wzorca do dopasowywania linii z innego pliku sed
, poniższe polecenie będzie działać poprawnie:
curl -d param1="$(sed -n '/matchpattern/p' file.txt)" -d param2=value2 http://example.com/submit
Teraz przejdź do problemu. Chcę pokazać tylko tekst między 2 pasującymi wzorami, z wyjątkiem samego pasującego wzoru.
Powiedzmy, że file.txt
zawiera:
Bla bla bla
firstmatch
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
secondmatch
The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.
Obecnie wiele sed
poleceń „między 2 pasującymi wzorami” nie usuwa firstmatch
i secondmatch
.
Chcę, aby wynik stał się:
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
text-processing
sed
lokomika
źródło
źródło
Odpowiedzi:
Oto jeden ze sposobów, w jaki możesz to zrobić:
Objaśnienie: Od pierwszej linii do linii pasującej do pierwszego dopasowania usuń. Od linii dopasowującej secondmatch do ostatniej linii usuń.
źródło
W awk:
źródło
Inne
sed
rozwiązanie zawiedzie, jeślifirstmatch
wystąpi w 1. linii 1 .Uprość to, użyj jednego zakresu i pustego 2 wyrażenia regularnego:
wydrukuj wszystko w tym zakresie z wyłączeniem końców zakresu (automatyczne drukowanie wyłączone) 3 :
lub, krócej, usuń wszystko spoza tego zakresu, a także usuń końce zakresu:
1: Powodem jest to, że jeśli drugi adres jest wyrażeniem regularnym, wówczas sprawdzanie dopasowania końcowego rozpocznie się od wiersza następującego po wierszu, który pasował do pierwszego adresu .
Dlatego
/firstmatch/
nigdy nie jest oceniany dla pierwszego wiersza wejścia,sed
po prostu go usunie, ponieważ pasuje do numeru wiersza,1,/RE/
i przejdzie do drugiego wiersza, w którym sprawdza, czy wiersz pasuje/firstpattern/
2: Gdy REGEX jest pusty (tj.
//
)sed
Zachowuje się tak, jakby podano ostatni REGEX użyty w ostatnim zastosowanym poleceniu (jako adres lub jako część polecenia zastępczego).3:
;}
składnia dotyczy nowoczesnychsed
implementacji; ze starszymi użyj albo nowej linii zamiast średnika, albo oddzielnych wyrażeń, npsed -n -e '/firstmatch/,/secondmatch/{//!p' -e '}' infile
źródło
//
się dzieje (w środku{…}
)?//
oznacza to ostatnie użyte wyrażenie regularne; ze wszystkiego, co przeczytałem, powinno być/secondmatch/
. Sprawdziłem, czy twoje polecenie działa, więc doszedłem do wniosku, że działa on tak jak/firstmatch|secondmatch/
(co potwierdziłeś), ale nie mogę znaleźć żadnej dokumentacji (nawet dokumentu POSIX, z którym się łączyłeś, ani GNU sed manual ), który opisuje to zachowanie. … (Ciąg dalszy)sed
: (1) Jeśli tak/first/,4
, to//
zachowuje się jak/first/
. (2) Jeśli tak2,/second/
,//
pojawia się błąd „brak poprzedniego wyrażenia regularnego”. (Uważam to za rażące zaniechanie podanego zachowania.) (3) Dodanie--posix
nie zmienia żadnego z powyższych. (II) W innych programach: (4) Wvi
, po/first/,/second/
,//
działa jak/second/
(a inne formy są racjonalnymi implementacjami udokumentowanej reguły). … (Ciąg dalszy)awk
wydaje się nie mieć pojęcia „ostatnio użyty składnik RE”;//
odnosi się do nie-znaku przed lub po dowolnym znaku. (Zapraszam do spróbowaniaecho -- | awk '{ gsub(//, "cha"); print }'
.)/first|second/
. Szczęściarz. Wspominam o innych programach, aby wykazać, że nie jest to jakaś ogólna systemowa konwencja wyrażeń regularnych. Ktokolwiek go dodał,sed
nie zawracał sobie głowy dodawaniem govim
, gdzie miałoby to tyle samo sensu. :-)