BASH: текст grep в длинной строке - PullRequest
0 голосов
/ 04 января 2019

Может кто-нибудь объяснить, как написать регулярное выражение для получения значения в очень длинный текстовый файл, полный мета. Весь файл без разделителей новой строки, только очень длинная строка, которую трудно прочитать или проанализировать

Мне нужно получить значения после ключа имени пользователя. Кто-нибудь может помочь? Кажется, застрял, выписывая правильное выражение регулярного выражения для этого случая

    .."somevalue\";s:7:\"text1\";s:8:\"username\";s:9:\"USER1\";s:7:\"company\";s:3:\"text2\";s:5:\  "somevalue\";s:11:\"text11\";s:8:\"username\";s:15:\"USER2\";s:7:\"company\";s:17:\"XXXX\";s:5:\...   "somevalue\";s:15:\"text110000\";s:8:\"username\";s:12:\"USER3_HERE\";s:7:\"company\";s:18:\"yyyyy\";s:

В приведенном выше примере мне нужен следующий вывод

    USER1
    USER2
    USER3_HERE

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Для ввода lokking, как это:

cat <<EOF >file
s:7:\"text1\";s:8:\"username\";s:9:\"USER1\";s:7:\"company\";s:3:\"text2\";s:5:\  "somevalue\";s:11:\"text11\";s:8:\"username\";s:15:\"USER2\";s:7:\"company\";s:17:\"XXXX\";s:5:\...   "somevalue\";s:15:\"text110000\";s:8:\"username\";s:12:\"USER3_HERE\";s:7:\"company\";s:18:\"yyyyy\";
EOF

Мы можем:

< file \
tr ';' '\n' |
sed 's/^.*:\\"\(.*\)\\"$/\1/' |
grep -x "USER1\|USER2\|USER3_HERE"
  • заменить ; на новую строку
  • отфильтровать текст между :\"...\"
  • grep только для строк USER1 USER2 или USER3_HERE
0 голосов
/ 04 января 2019

С Perl это

perl -wn -le 'print for /\\"username\\";.*?\\"([^\\"]+)/g' filename

-n - построчно обрабатывать файл, но ничего не печатать

-l - обрабатывать окончания строк

-e - запустите следующий код

print for /\\"username\\";.*?\\"([^\\"]+)/g

Печатайте захваченный вывод всякий раз, когда вы видите \"username\";, за которым следует что-то, за которым следует \".

выход

$ perl -wn -le 'print for /\\"username\\";.*?\\"([^\\"]+)/g'
    .."somevalue\";s:7:\"text1\";s:8:\"username\";s:9:\"USER1\";s:7:\"company\";s:3:\"text2\";s:5:\  "somevalue\";s:11:\"text11\";s:8:\"username\";s:15:\"USER2\";s:7:\"company\";s:17:\"XXXX\";s:5:\...   "somevalue\";s:15:\"text110000\";s:8:\"username\";s:12:\"USER3_HERE\";s:7:\"company\";s:18:\"yyyyy\";s:

USER1
USER2
USER3_HERE

Смотри также

perlrun для переключателей командной строки

perlre для используемого регулярного выражения

0 голосов
/ 04 января 2019

С GNU awk (для ясности я добавил распечатку номера поля с печатью i перед $i):

$ gawk 'BEGIN{FS="\\\\\""} {for (i=1;i<=NF;i++) if (match($i, /USER/)) print i, $i}' file
7 USER1
18 USER2
29 USER3_HERE

Если вы хотите, чтобы поле следовало за этими полями:

$ gawk 'BEGIN{FS="\\\\\""} {for (i=1;i<=NF;i++) if (match($i, /USER/)) print $i, $(i+1)}' file
USER1 ;s:7:
USER2 ;s:7:
USER3_HERE ;s:7:

Вы можете использовать GNU grep:

$ ggrep -oP 'USER[^;]*;([^\\]*)\\"company' file
USER1\";s:7:\"company
USER2\";s:7:\"company
USER3_HERE\";s:7:\"company

Или Perl, если вам нужна группа совпадений:

$ perl -lnE 'say for /USER[^;]*;([^\\]*)\\"company/g' file
s:7:
s:7:
s:7:
...