Używanie wyrażenia regularnego zgodnego z Perlem z GNU grep -P

10

Używam tego wyrażenia regularnego (?<=\[')[^,]*w pliku zawierającym następujący wierszdisk = ['OVS/sdasd/asdasd/asdasd/something.img, w']

Chcę to wrócić OVS/sdasd/asdasd/asdasd/something.img

Jak używać, grepaby działało?

Próbowałem, grep -P "(?<=\[')[^,]*"ale zwraca całą linię.

GxFlint
źródło

Odpowiedzi:

14

Dodaj -oprzełącznik, aby grepzwracał tylko to, co pasuje do wzoru, którego szukasz:

$ grep -Po "(?<=\[')[^,]*" data.txt 
OVS/sdasd/asdasd/asdasd/something.img
slm
źródło
6

Można również użyć sedbez potwierdzenia, aby zapewnić większą przenośność ( -omoże nie być dostępne dla Twojego grep):

sed "s!['\(\[^,\]*\),.*\$!\1!;t;d;p" data.txt

Uwaga: „dziwne” użycie odwrotnego ukośnika ucieka tutaj. Wynika to z faktu, że seddomyślnie korzysta z BRE (patrz to pytanie ).

Mówiąc o przenośności, dlaczego nie skorzystać z Perla?

perl -nle "print \$1 if /\['([^,]*)/" data.txt
Joseph R.
źródło
2

@slm już dał ci odpowiedź kanoniczną. Oto kilka innych opcji:

Użyj awki 'jako ogranicznika pola (zakładając, że wszystkie wiersze mają ten sam format):

$ awk -F "'" '($1~/ = /){print $2}'
OVS/sdasd/asdasd/asdasd/something.img, w    

Zrób wszystko w Perlu:

$ perl -lne 'print $1 if /\[.(.*?).\]/' data.txt 
OVS/sdasd/asdasd/asdasd/something.img, w    

Użyj prostszego wyrażenia regularnego i przeanalizuj wyniki:

$ grep "\[.*\]" data.txt | awk -F "'" '{print $2}'
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep -o "\[.*\]" data.txt | perl -pe "s/[\[\]']//g"
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep "\[.*\]" data.txt | sed 's/.*\[.\(.*\).\]/\1/'
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep "\[.*\]" data.txt | perl -pne 's/.*\[.(.*?).\].*/$1/'
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep "\[.*\]" data.txt | perl -lne 'print $1 if /\[.(.*?).\]/'
OVS/sdasd/asdasd/asdasd/something.img, w
terdon
źródło