Grep:计算如果没有出现另一个字符串,则出现一个字符串的次数

时间:2019-04-05 03:17:46

标签: grep

我有一组许多.json.gz文件。在每个文件中,都有这样的条目:

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

无论每个嵌套词典“ login”出现在哪里,我都希望能够检测到它并采用用户名,只要密钥“ org”在嵌套词典中的任何位置都不存在。我还想计算每个用户名出现在文件中的次数。

我的最终输出应该是如下所示的dict文件:

{'username2: 1}

因为当然不会计算用户名1:键“ org”出现在其字典中。

我正在寻找类似的东西

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" . | 

其余的文件成功创建了我要查找的文件类型。我只是不确定这里的操作顺序。

编辑

抱歉,我应该更清楚。每个主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出现在第二个字典中,因此我想从我创建并保存到文件的字典中排除用户名3和4。

例如,我想要在文件中输入

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

3 个答案:

答案 0 :(得分:0)

不是grep,而是带有脚本的gnu sed作业,您的数据位于'a'

second

最后使用'>'保存到文件中

如果使用更好的regex:安装了'pcregrep',那么效果也不错;

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

替换上面的sed ...脚本,并调整打印输出

答案 1 :(得分:0)

AWK解决方案,并用更可靠的find代替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}

答案 2 :(得分:0)

这有效:

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