Я использую это регулярное выражение (?<=\[')[^,]*
для файла, содержащего следующую строкуdisk = ['OVS/sdasd/asdasd/asdasd/something.img, w']
Я хочу, чтобы это вернулось.OVS/sdasd/asdasd/asdasd/something.img
Как мне это использовать, grep
чтобы это работало?
Я пробовал grep -P "(?<=\[')[^,]*"
, но возвращается вся строка.
решение1
Добавьте -o
переключатель, чтобы grep
возвращать только то, что соответствует шаблону, который вы ищете:
$ grep -Po "(?<=\[')[^,]*" data.txt
OVS/sdasd/asdasd/asdasd/something.img
решение2
Вы также можете использовать sed
без утверждения lookaround для большей переносимости ( -o
может быть недоступно для вашего grep
):
sed "s!['\(\[^,\]*\),.*\$!\1!;t;d;p" data.txt
Обратите внимание на «странное» использование экранирования обратной косой черты. Это связано с тем, что sed
по умолчанию используются BRE (см.этот вопрос).
Говоря о переносимости, почему бы просто не использовать Perl?
perl -nle "print \$1 if /\['([^,]*)/" data.txt
решение3
@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