Po prostu muszę uzyskać dopasowanie z wyrażenia regularnego:
$ cat myfile.txt | SOMETHING_HERE "/(\w).+/"
Wyjście musi być tylko tym, co zostało dopasowane, w nawiasie.
Nie sądzę, że mogę użyć grep, ponieważ pasuje do całej linii.
Daj mi znać, jak to zrobić.
sed
rereferencjami, aby to zrobić?źródło
Jeśli chcesz tylko tego, co jest w nawiasach, potrzebujesz czegoś, co obsługuje przechwytywanie pod dopasowań (nazwane lub numerowane grupy przechwytywania). Nie sądzę, że grep lub egrep mogą to zrobić, perl i sed mogą. Na przykład za pomocą perla:
Jeśli plik o nazwie foo ma linię, wygląda to następująco:
I robisz:
Litera a jest zwracana. To może nie być to, czego chcesz. Jeśli powiesz nam, co próbujesz dopasować, możesz uzyskać lepszą pomoc. 1 USD to kwota uchwycona w pierwszym zestawie nawiasów. 2 USD będzie drugim zestawem itp.
źródło
Ponieważ otagowałeś swoje pytanie jako bash oprócz powłoki , istnieje inne rozwiązanie oprócz grep :
Bash ma swój własny silnik wyrażeń regularnych od wersji 3.0, wykorzystujący
=~
operator, podobnie jak Perl.teraz, biorąc pod uwagę następujący kod:
bash
nie tylkosh
w celu uzyskania wszystkich rozszerzeń$BASH_REMATCH
da cały ciąg zgodny z całym wyrażeniem regularnym, więc<Lane>8</Lane>
${BASH_REMATCH[1]}
da część dopasowaną przez 1. grupę, a więc tylko8
źródło
>
symbol do zupełnie innych celów), które zostały wyrzucone przez oprogramowanie SANSparallel do szybkiego dostosowywania na dużą skalę . Oczywiście oba formaty są przeplatane bez przeplotu. Dlatego nie można wrzucić do tego jakiejś standardowej biblioteki XML. I używam wyrażenia regularnego Bash w tym miejscu kodu, ponieważ muszę tylko wyodrębnić kilka danych, a 2 wyrażenia regularne wykonują dla mnie zadanie znacznie lepiej niż pisanie dedykowanego analizatora składni dla tego bałaganu. #LifeInBioinformaticsZakładając, że plik zawiera:
I chcesz znaków między
>
i</
, możesz użyć albo:grep
grep -oP '.*\K(?<=>)\w+(?=<\/)' file
sed
sed -nE 's:^.*>(\w+)</.*$:\1:p' file
awk
awk '{print(gensub("^.*>(\\w+)</.*$","\\1","g"))}' file
perl
perl -nle 'print $1 if />(\w+)<\//' file
Wszystko wypisze ciąg „xyz”.
Jeśli chcesz uchwycić cyfry tej linii:
grep
grep -oP '.*\K(?<=>)[0-9]+(?=<\/)' file
sed
sed -E 's:^.*>([0-9]+)</.*$:\1:' file
awk
awk '{print(gensub(".*>([0-9]+)</.*","\\1","g"))}' file
perl
perl -nle 'print $1 if />([0-9]+)<\//' file
źródło
echo 'Text-<here>1234</text>-ends' | sed -E 's|.*>([[:digit:]]+)<.*|\1|'
. W niektórych przypadkach (np.[0-9]
Vs.[[:digit:]]
) nie pomagają one w czytelności, w innych myślę, że tak (np.[ \t\n\r\f\v]
Vs.[:space:]
).Dzięki temu osiągniesz to, o co prosisz, ale nie sądzę, że tego naprawdę chcesz. Umieszczam
.*
przed regexem, aby zjeść wszystko przed dopasowaniem, ale jest to chciwa operacja, więc pasuje to tylko do przedostatniego\w
znaku w ciągu.Pamiętaj, że musisz uciec przed parens i
+
.źródło