Извлечь совпадения с образцом / удалить все из строки, кроме образца - PullRequest
1 голос
/ 29 мая 2019

В настоящее время я использую grep, чтобы попытаться извлечь конкретный текст из каждой строки файла. Он успешно извлекает совпадения, однако я хотел бы, чтобы он сохранил все строки, у которых нет совпадений (оставьте их как пустую строку).

Это то, что я пробовал до сих пор (чтобы получить название города в каждой строке):

grep -o -P '(?<="city":").*?(?=")' input.txt

Пример ввода:

email":"addictedtotlick7@gmail.com","last_name":"THOMPSON","first_name":"ERIN",,"__v":0,,,,"state":"NY","city":"north tonawanda"}
first_name":"chris","last_name":"caul",,"email":"dawgzn@mail.com",,,,"__v":0}
email":"lesliebo993@hotmail.com",,"first_name":"LESLIE","last_name":"RAMBO",,"city":"DOTHAN","state":"AL",,,"__v":0,
email":"malala@yahoo.com",,,"state":"GA","city":"NORCROSS",,"last_name":"KEO","first_name":"CATHY",,"__v":0,
email":"kdela@gmail.com",,"state":"FL","city":"HOLLYWOOD",,"last_name":"DE LA CRUZ","first_name":"KIDA",,"__v":0,

Желаемый вывод:

north tonawanda

DOTHAN
NORCROSS
HOLLYWOOD

Рад попробовать что-то в SED, если это проще, но предпочел бы избегать AWK, так как мне приходится работать с большими файлами, но я не уверен, что у меня достаточно оперативной памяти.

Ответы [ 4 ]

0 голосов
/ 29 мая 2019

Вы можете попробовать Perl

$ perl -nle ' if(/"city":"(.*?)"/) { print $1 } else { print "" } ' input.txt
north tonawanda

DOTHAN
NORCROSS
HOLLYWOOD

$
0 голосов
/ 29 мая 2019

Я предлагаю другой сценарий awk

awk 'match($0,/(?<=\"city\":\").*?(?=\")/,m){$0=m[0]}1' input.txt

Нет проблем с оперативной памятью и awk.

Этот скрипт обрабатывает каждую строку.Если текущая строка соответствует RegExp (?<="city":").*?(?="), то перезаписать текущую строку соответствием.Напечатать текущую строку.

0 голосов
/ 29 мая 2019

Сед:

sed 's/.*city":"\([^"]*\).*/|\1/; /^[^|]/s/.*//; s/^|//'
0 голосов
/ 29 мая 2019

Вы можете сделать это с помощью GNU awk:

gawk '{print index($0, "\"city\":\"") == 0 ? "" : gensub(/.*\"city\":\"([^\"]*).*/, "\\1", 1);}' file > newfile

Это означает: если в строке есть "city":" (index($0, "\"city\":\"") == 0), то (?) выведите пустую строку ("") или (:) выведите результат замены gensub(/.*\"city\":\"([^\"]*).*/, "\\1", 1) регулярного выражения:

  • .* - любые 0+ символов
  • \"city\":\" - a "city":" подстрока
  • ([^\"]*) - Группа захвата 1 (\1): любые 0+ символов, кроме "
  • .* - любые 0+ символов.

Результатом этого является значение группы 1. Нам нужен gensub и, следовательно, GNU awk, поскольку нам нужен доступ к значению группы захвата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...