Использование регулярного выражения, совместимого с Perl, с GNU grep -P

10

Я использую это регулярное выражение (?<=\[')[^,]*в файле, содержащем следующую строкуdisk = ['OVS/sdasd/asdasd/asdasd/something.img, w']

Я хочу это вернуть OVS/sdasd/asdasd/asdasd/something.img

Как мне использовать, grepчтобы это работало?

Я пытался, grep -P "(?<=\[')[^,]*"но он возвращает всю строку.

GxFlint
источник

Ответы:

14

Добавьте -oпереключатель, чтобы он grepвозвращал только то, что соответствует шаблону, для которого вы выполняете поиск:

$ grep -Po "(?<=\[')[^,]*" data.txt 
OVS/sdasd/asdasd/asdasd/something.img
SLM
источник
6

Вы также можете использовать sedбез дополнительного подтверждения для большей мобильности ( -oможет быть недоступно для вашего grep):

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

Обратите внимание на «странное» использование обратной косой черты здесь. Это связано с тем, что sedпо умолчанию используются BRE (см. Этот вопрос ).

Говоря о переносимости, почему бы просто не использовать Perl?

perl -nle "print \$1 if /\['([^,]*)/" data.txt
Джозеф Р.
источник
2

@slm уже дал вам канонический ответ. Вот еще несколько вариантов:

Используйте awkи 'как разделитель полей (при условии, что все строки имеют одинаковый формат):

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

Сделайте все это в Perl:

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

Используйте более простое регулярное выражение и проанализируйте результаты:

$ 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
Тердон
источник