Mam polecenie, które wyprowadza dane do stdout ( command1 -p=aaa -v=bbb -i=4
). Linia wyjściowa może mieć następującą wartość:
rate (10%) - name: value - 10Kbps
Chcę grepować ten wynik, aby zapisać tę „szybkość” (myślę, że fajka będzie tu przydatna). Na koniec chciałbym, aby ta szybkość była wartością parametru drugiego polecenia (powiedzmy command2 -t=${rate}
)
Z mojej strony wydaje się to trudne. Chciałbym wiedzieć lepiej, jak używać rur, grep, sed i tak dalej.
Próbowałem wielu takich kombinacji, ale mylę się z tymi:
$ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate}
Aby zasymulować dane wyjściowe
command1
używam tej instrukcji echa:Szybki test:
To wszystko dobrze, więc przeanalizujmy to:
Więc otrzymujemy linię, z której chcemy
command1
, przepuszczamy to docommand2
:Spodziewam
"rate was "$(command1 | grep 'rate')
się konkatenacji automatycznie. Jeśli to nie działa z powodu białych znaków, powinieneś być w stanie przekazać dane wejściowe w ten sposób:źródło
Spróbuj tego za pomocą grep & pcre :
źródło
Pierwszym zadaniem jest wyodrębnienie stawki z tej linii. W GNU grep (niewbudowany Linux lub Cygwin) możesz skorzystać z tej
-o
opcji. Część, którą chcesz, to ta, która zawiera tylko cyfry, a po niej%
znak. Jeśli nie chcesz wyodrębnić%
samego siebie, potrzebujesz dodatkowej sztuczki: asertywne stwierdzenie zerowej szerokości , które nie pasuje do niczego, ale tylko wtedy, gdy po nim nie następuje nic%
.Inną możliwością jest użycie sed. Aby wyodrębnić część linii w sed, użyj
s
polecenia z wyrażeniem regularnym pasującym do całej linii (zaczynając od^
i kończąc na$
), z częścią do zachowania w grupie (\(…\)
). Zastąp całą linię zawartością grup, które chcesz zachować. Ogólnie rzecz biorąc, przekaż-n
opcję wyłączenia domyślnego drukowania i wstawp
modyfikator do drukowania linii, w których jest coś do wyodrębnienia (tutaj jest jedna linia, więc to nie ma znaczenia). Zobacz Zwracanie tylko części linii po pasującym wzorcu i Wyodrębnianie wyrażenia regularnego dopasowanego do „sed” bez drukowania otaczających znaków, aby uzyskać więcej sztuczek sed.Bardziej elastyczny niż sed, jest awk. Awk wykonuje instrukcje dla każdej linii w małym imperatywnym języku. Istnieje wiele sposobów wyodrębnienia stawki; Zaznaczam drugie pola (pola są domyślnie ograniczone białymi spacjami) i usuwam wszystkie znaki, które nie są cyframi.
Następnym krokiem, po wyodrębnieniu stawki, jest przekazanie jej jako argumentu
command2
. Narzędziem do tego jest zawieszenie polecenia . Jeśli umieścisz polecenie w środku$(…)
(nawias dolara), jego dane wyjściowe zostaną podstawione w linii poleceń. Dane wyjściowe polecenia są dzielone na osobne słowa w każdym bloku białych znaków, a każde słowo jest traktowane jako wzór wieloznaczny; chyba że chcesz to się stało, umieścić w cudzysłowie podstawienia polecenia:"$(…)"
. W przypadku podwójnych cudzysłowów dane wyjściowe polecenia są używane bezpośrednio jako pojedynczy parametr (jedyną transformacją jest to, że znaki nowej linii na końcu danych wyjściowych są usuwane).źródło
Możesz używać,
grep
a to PCRE - wyrażenia regularne zgodne z Perlem. Pozwala to na użycie opcji lookbehind, aby dopasować wartość rate, bez włączania ciągu „rate” w wynikach podczas szukania go.Przykład
Detale
Powyższe
grep
działa w następujący sposób:-o
zwróci tylko to, czego szukamy\d+
, czyli cyfry w parens.-P
włącza funkcję PCRE grep(?<=^rate \()
zwróci tylko ciągi rozpoczynające się od „rate (”polecenie 2
Aby złapać wartość „stawki”, możesz uruchomić
command1
tak:Następnie dla drugiego polecenia wystarczy użyć tej zmiennej.
Możesz mieć ochotę i zrobić jedną linię:
Spowoduje to wykonanie polecenia 1 w
$(..)
bloku wykonawczym, pobranie jego wyników i włączenie ich do-t=..
przełącznika polecenia 2.źródło
Zasadniczo używam `command` do umieszczenia jego wyniku jako argumentu w innym poleceniu. Na przykład, aby znaleźć zasoby zużywane przez proces foo na freebsd będzie:
Tutaj pgrep służy do wyodrębnienia PID procesu foo, który jest przekazywany do komendy procstat, która oczekuje PID procesu jako argumentu.
źródło