Mam taki plik prova.txt
:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
extra1
extra2
bla
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
extra2
bla
bla
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
i muszę przejść z „Zacznij chwytać tutaj” do pierwszej pustej linii. Dane wyjściowe powinny wyglądać następująco:
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131
Jak widać, wiersze po „Zacznij chwytać tutaj” są losowe, więc flaga -A -B grep nie działa:
cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt
Czy możesz mi pomóc znaleźć sposób na złapanie pierwszej linii, która zostanie złapana (jako „Zacznij chwytać stąd”), aż do pustej linii. Nie mogę przewidzieć, ile losowych linii będę mieć po „Zacznij chwytać stąd”.
Każde rozwiązanie kompatybilne z Uniksem jest mile widziane (grep, sed, awk jest lepsze niż Perl lub podobny).
ZMIENIONO: po genialnej odpowiedzi @ john1024 chciałbym wiedzieć, czy można:
1 ° posortuj blok (według Start, aby pobrać stąd: 1, a następnie 1, a następnie 2)
2 ° usuń 4 (losowo alfabetycznie) linie fix1, fix2, fix3, fix4, ale zawsze są 4
3 ° ostatecznie usuwa losowe duplikaty, takie jak polecenie sort -u
Ostateczne wyjście powinno wyglądać następująco:
# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4
#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
lub
# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131
#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561
Drugie wyjście jest lepsze niż pierwsze. Potrzebna jest inna magia poleceń unixa.
źródło
Odpowiedzi:
Korzystanie z awk
Próbować:
/Start to grab/,/^$/
określa zakres. Zaczyna się od dowolnej pasującej linii,Start to grab
a kończy pierwszą pustą linią^$
.Korzystanie z sed
Z bardzo podobną logiką:
-n
mówi sed, aby niczego nie drukował, chyba że wyraźnie o to poprosimy./Start to grab/,/^$/p
każe mu wydrukować dowolne linie w zakresie zdefiniowanym przez/Start to grab/,/^$/
.źródło
Zamieszczam alternatywne rozwiązanie, ponieważ może być przydatne w niektórych przypadkach użycia. To rozwiązanie nie spełnia dokładnie podanych wymagań, najlepsze rozwiązanie znajdziesz w odpowiedzi na @ John1024.
Możesz użyć awk z ustawionym separatorem rekordów na pusty ciąg, awk zinterpretuje je jako puste znaki nowej linii:
Ta wersja nie zachowuje pustych znaków nowej linii na wyjściu. Pokaże także kontekst przed meczem, jeśli jest obecny. To zachowanie może być bardzo przydatne, gdy szuka się czegoś w pliku, a chcesz zobaczyć blok rozdzielany znakiem nowej linii, którego jest częścią, na przykład:
Na przykład uważam to za przydatne, gdy szukam rzeczy w
ini
plikach.źródło