Jeśli masz GNU grep, możesz użyć jego -o
opcji, aby wyszukać wyrażenie regularne i wypisać tylko pasującą część. (Inne implementacje grep mogą wyświetlać tylko całą linię.) Jeśli w jednym wierszu jest kilka dopasowań, są one drukowane w osobnych wierszach.
grep -o '\[[0-9]*\]'
Jeśli chcesz tylko cyfry, a nie nawiasy, jest to trochę trudniejsze; musisz użyć asercji o zerowej szerokości: wyrażenie regularne pasujące do pustego ciągu, ale tylko wtedy, gdy jest poprzedzone lub, w zależności od przypadku, po nawiasie. Asercje o zerowej szerokości są dostępne tylko w składni Perla.
grep -P -o '(?<=\[)[0-9]*(?=\])'
Za pomocą sed musisz wyłączyć drukowanie -n
i dopasować całą linię i zachować tylko pasującą część. Jeśli w jednym wierszu jest kilka możliwych dopasowań, drukowane jest tylko ostatnie dopasowanie. Zobacz Wyodrębnianie wyrażenia regularnego dopasowanego do „sed” bez drukowania otaczających znaków, aby uzyskać więcej informacji na temat używania sed tutaj.
sed -n 's/^.*\(\[[0-9]*\]\).*/\1/p'
lub jeśli chcesz tylko cyfry, a nie nawiasy:
sed -n 's/^.*\[\([0-9]*\)\].*/\1/p'
Bez tego grep -o
Perl jest tu z wyboru narzędziem, jeśli chcesz czegoś, co jest zarówno proste, jak i zrozumiałe. W każdym wierszu ( -n
), jeśli wiersz zawiera dopasowanie dla \[[0-9]*\]
, wydrukuj to dopasowanie ( $&
) i znak nowej linii ( -l
).
perl -l -ne '/\[[0-9]*\]/ and print $&'
Jeśli chcesz tylko cyfr, umieść nawiasy w wyrażeniu regularnym, aby wyznaczyć grupę, i wydrukuj tylko tę grupę.
perl -l -ne '/\[([0-9]*)\]/ and print $1'
PS Jeśli chcesz wymagać tylko jednej lub więcej cyfr między nawiasami, zmień [0-9]*
na [0-9][0-9]*
lub na [0-9]+
Perl.
[number]
” oznacza oprócz[0-9]
perl
wyrażenia regularne wyglądają na naprawdę przydatne! Czytałem o nich po tym, jak zobaczyłem, że używasz zarówno twierdzeń do tyłu, jak i do przodu, nawet w grep (przełączyłem się na fakt, że możesz wybrać silnik wyrażeń regularnych). Odtąd poświęcę nieco więcej czasu na użycie wyrażenia regularnego Perla. Dzięki ... PS .. Właśnie przeczytałemman grep
... "Jest to bardzo eksperymentalne i grep -P może ostrzegać przed niewdrożonymi funkcjami." ... Mam nadzieję, że to nie oznacza niestabilności (?) ...Nie możesz tego zrobić
cut
.tr -c -d '0123456789\012'
sed 's/[^0-9]*//g'
awk -F'[^0-9]+' '{ print $1$2$3 }'
grep -o -E '[0-9]+'
tr
jest najbardziej naturalnym rozwiązaniem problemu i prawdopodobnie działałby najszybciej, ale myślę, że potrzebujesz gigantycznych danych wejściowych, aby oddzielić każdą z tych opcji pod względem prędkości.źródło
^.*
jest chciwy i zużywa wszystko oprócz ostatniej cyfry i+
musi być\+
albo użyć posix\([0-9][0-9]*\)
... a w każdym razie's/[^0-9]*//g'
działa równie dobrze,... Thanks for the
tr -c` przykład, ale czy to nie jest\012
zbyteczne?\012
: jest potrzebny, inaczejtr
zje nowe linie.\0
,1
,2
(lub nawet \, 0, 1, 2). Wygląda na to, że nie jestem wystarczająco dostrojony do ósemki. Dzięki.Jeśli masz na myśli wyodrębnić zestaw kolejnych cyfr między znaki nie-cyfrowych, myślę
sed
iawk
są najlepsze (choćgrep
jest w stanie dać Ci dopasowane znaków):sed
: możesz oczywiście dopasować cyfry, ale być może interesujące jest zrobienie czegoś odwrotnego, usunięcie cyfr niebędących cyframi (działa, o ile jest tylko jedna liczba w linii):grep
: możesz dopasowywać kolejne cyfryNie podam przykładu,
awk
ponieważ nie mam z tym doświadczenia; warto zauważyć, że chociażsed
jest szwajcarskim nożem,grep
daje to prostszy, bardziej czytelny sposób, aby to zrobić, który działa również dla więcej niż jednej liczby w każdej linii wejściowej (-o
tylko drukuje pasujące części wejścia, każda na własnej linii):źródło
sed
eqivalent z „więcej niż jeden numer na linię” przykładgrep -o '[[:digit:]]*'
. . .sed -nr '/[0-9]/{ s/^[^[0-9]*|[^0-9]*$//g; s/[^0-9]+/\n/g; p}'
... (+1)Ponieważ powiedziano, że nie można tego zrobić
cut
, pokażę, że łatwo jest stworzyć rozwiązanie, które nie jest co najmniej gorsze od niektórych innych, nawet jeśli nie popieram stosowania tegocut
jako „najlepszego” (lub nawet szczególnie dobre) rozwiązanie. Należy powiedzieć, że każde rozwiązanie, które nie szuka dokładnie cyfr*[
i]*
wokół cyfr, upraszcza założenia i dlatego jest podatne na błędy na przykładach bardziej złożonych niż podane przez pytającego (np. Cyfry na zewnątrz*[
i]*
, których nie należy pokazywać). To rozwiązanie sprawdza przynajmniej nawiasy klamrowe i można je rozszerzyć również o gwiazdki (pozostawione jako ćwiczenie dla czytelnika):Wykorzystuje to
-d
opcję określającą separator. Oczywiście możesz równieżcut
przesyłać do wyrażenia zamiast czytać z pliku. Chociażcut
jest prawdopodobnie dość szybki, ponieważ jest prosty (bez silnika wyrażenia regularnego), musisz wywołać go co najmniej dwa razy (lub kilka razy, aby sprawdzić*
), co powoduje pewne obciążenie procesu. Jedyną prawdziwą zaletą tego rozwiązania jest to, że jest raczej czytelny, szczególnie dla zwykłych użytkowników, którzy nie są dobrze zaznajomieni z konstrukcjami regularnymi.źródło