Grep: подсчитать, сколько раз встречается строка, если другая строка не встречается - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть множество файлов .json.gz.В каждом файле есть записи, такие как это:

{"type":"e1","public":true, "login":"username1", "org":{"dict","of":"lots_of_things"}}
{"type":"e2","public":true, "login":"username2"}

Независимо от того, где в каждом вложенном диктанте появляется «логин», я хочу иметь возможность обнаружить его и взять имя пользователя, только если ключ »org "не существует нигде во вложенном dict.Я также хочу посчитать, сколько раз каждое имя пользователя появляется в файлах.

Мой окончательный вывод должен быть файлом dicts, который выглядит следующим образом:

{'username2: 1}

, потому что, конечно, username1 не будет учитываться: ключ "org" появляется в его dict.

Я ищу что-то вроде:

zgrep -Rv "org" . | zgrep -o 'login":"[^"]*"' /path/to/files/* | cut -d'"' -f3 | sort | uniq -c | sed '1i{
       s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}' > outputfile.txt

Я не уверен насчет этой части:

zgrep -Rv "org" . | 

Остальное успешно создает тип файла I 'ищуЯ просто не уверен насчет порядка операций здесь.

РЕДАКТИРОВАТЬ

Я должен был быть более ясным, я прошу прощения.Также часто имеется несколько экземпляров ключа «логин» на главный объект dict.Например (используя «k» для любого ключа, который не является логином и не org, и используя «v» для значения):

{"k":"v","k":{"k":{"k":"v","login":"username1"},"k":"v"},"k":{"k":"v","login":"username2"}}
{"k":{"k":"v","k":"v"},"k":{"org":{"k":"v","k":v,"login":"username3"},"k":"v"},"k":{"k":"v","login":"username4"}}
{"k":{"k":"v"},"k":{"k":{"k":"v","login":"username1"},"login":"username2"}}

, так как ключ org появляется во втором dict, яхочу исключить имена пользователей 3 и 4 из указания, которое я создаю, и сохранить в файл.

Например, я хочу это в файле:

{'username1': 2}
{'username2': 2}

Ответы [ 3 ]

0 голосов
/ 05 апреля 2019

AWK решение и замена find -R на более надежную находку:

find . -type f -name "*.json.gz" -print0 | xargs -0 zgrep -v -h '"org"' | awk '{ if ( match($0,/"login":"[^"]+"/) ) logins[substr($0,RSTART+8,RLENGTH-8)]++; } END { for ( i in logins ) print("{" i ":" logins[i] "}"); }'

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

{"username2":1}
0 голосов
/ 10 апреля 2019

Это сработало:

zgrep -v "org" *.json.gz | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c | sed '1i{
       s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}' > usernames_2011.txt
0 голосов
/ 05 апреля 2019

не grep, а gnu sed с помощью скрипта, ваши данные в 'a'

i=
for e in $(sed -nE '/.*\borg\b.*/!s/.*"login":"(\w+)".*/{\1:}/p' a)
{
let i++;echo ${e/:/:$i}
}

используйте '>' в конце, чтобы сохранить в файл

если лучше regex: 'pcregrep' установлен, то он тоже работает;

pcregrep -io '(?!.*\borg\b.*)(?<="login":")\w+(?=".*)' a

замените скрипт sed ... выше, с немного скорректированной распечаткой

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