Chcę policzyć linie między znakami „X”. To tylko przykład; Muszę zastosować kod do złożonego wyniku biologicznego. Będę wdzięczny, jeśli można zasugerować jakieś polecenie, najlepiej przy użyciu awk
, grep
lub sed
jak jestem zaznajomiony z tymi.
Przykład:
X
Y
Y
Y
X
Y
Y
Y
Y
X
Y
X
Pożądane wyjście:
3
4
1
Odpowiedzi:
Z
awk
:Zwiększ liczbę dla każdej linii niezawierającej
X
; wydrukuj i zresetuj liczbę wierszy zawierającychX
.źródło
X
, pierwsza liczba linii byłaby nadal liczona i wysyłana za pomocą tego rozwiązania, aż doX
dopasowania pierwszej linii z . EX (Nie można dodawać nowych wierszy w komentarzach, ale należy wziąć pod uwagę, że między każdym znakiem jest nowy wiersz; P):Y X Y Y X Y Y Y
wyświetli:1 2
END{if (count)print count}
), a tworzenie pustej linii, w której X był na początku, aby uniknąć dodania/X/&&count
warunku równieżY
nie należy liczyć, ponieważ nie są dokładnie między dwomaX
; drugi narzeka, że końcoweY
s nie są liczone, ponieważ nie są dokładnie między dwomaX
s. W razie potrzeby poczekam na wyjaśnienie PO; Nie mam nic przeciwko tej odpowiedzi do chwili obecnej.Jak to działa:
Awk domyślnie czyta pliki wejściowe linia po linii.
/X/ && prev{print NR-prev-1}
Dla każdego wiersza, który zawiera
X
i jeśli wcześniej przypisaliśmy wartośćprev
, wydrukuj numer bieżącego wierszaNR
, minusprev
minus jeden./X/{prev=NR}
Dla każdego wiersza zawierającego
X
ustawić zmiennąprev
do bieżącego numeru linii,NR
.źródło
NR
daje mi pomysł:awk '/X/{print NR - 1; NR = 0}' foo
X
, istnieje niewielka różnica w wynikach między 2 odpowiedziami, jak wyjaśniłem w komentarzu pod odpowiedzią Muru.Kolejne proste
awk
podejście, które działa na przykładowych danych OP i jeśliX
nie było w pierwszym, a nawet w ostatnich lub powtórzonych Xs.Powyższe jest poprawne, gdy w każdym wierszu znajduje się tylko jedno pole z domyślnym FS dowolnymi białymi spacjami , w przeciwnym razie poniżej poprawiono ogólny przypadek liczenia linii . Można wprowadzać swoje PATTERN w miejsce X tam.
Przykładowe dane wejściowe:
Dane wyjściowe to:
źródło
Większość odpowiedzi tutaj odpowiada zawartości wiersza, który ma być policzony przy użyciu wyrażeń regularnych osadzonych w programie Awk. Jeśli chcesz dopasować wiersze do treści, które mogą zawierać znaki specjalne (do Awk lub wyrażeń regularnych), lepiej byłoby faktycznie porównać ciągi znaków dla równości. Dlatego proponuję następujący skrypt Awk jako wariant odpowiedzi muru :
Zapisz go jako plik tekstowy
count-rows.awk
i wywołaj go w następujący sposób:Możesz dostosować wartość
needle
do swoich upodobań. Zaletą tej metody jest to, że można wywoływać program ze skryptu powłoki o dowolnej wartościneedle
bez uciekania się przed problemami:źródło