从无效的 3GB .json 文件生成具有特定内容的 .txt 文件

从无效的 3GB .json 文件生成具有特定内容的 .txt 文件

我有一个名为 users.json 的文件,大小为 3GB,并且是无效的 json。所以我想做的是读取文件的文本内容,并获取我需要的信息,即文件中包含的用户名,并将它们写入 usernames.txt 文件,该文件每行应包含 1 个用户名,其中没有重复项。

json 文件中用户名的格式如下: "username":"someUsername"

如何收集所有用户名,将它们放入文本文件中并确保没有重复?

我已经通过 Node.js 和 PHP 进行了尝试,但还没有任何有效的工作,希望使用 bash 可以完成一些很酷的事情。

文件中包含的数据示例(可能没有太大帮助,因为我已经提到了格式"username":"someUsername"):

username":"satish_nanded","original_ff_id":"99554"},"100003":{"username":"sweetnamu","original_ff_id":"100003"}},"08fdlhNuZEM1z8q4mQftYUtO7uC3":{"575511":{"username":"lrlgrdnr","original_ff_id":"575511"}},"08fe4Dg7NeOTItq3b9Pi8ORsX5J2":{"59520":{"username":"joneljon","original_ff_id":"59520"}},"08gsZHsbm9Rew4S2IqcbGvD9Fct1":{"724707":{"username":"jacksonc4565","original_ff_id":"724707"}

答案1

您可以使用该grep命令来匹配所需的模式,并sort过滤掉重复项。如果您的输入文件是input.json并且输出是usernames.txt

grep -P -o '(?<="username":")[^"]*' input.json | sort -u > usernames.txt

分解一下:

  • grep是一个用于匹配文件中正则表达式的命令行实用程序。正则表达式是描述您希望查找的文本片段的有效方法
  • -P告诉grep我们使用“Perl 兼容正则表达式”。请注意,grep 的手册页将其描述为“高度实验性”!
  • -o告诉grep只输出匹配的文本。默认情况下,grep只要找到匹配项,通常会输出整行。
  • '(?<="username":")[^"]*'是正则表达式本身:
    • 我们将其放在单引号中'....'以阻止命令行 shell 尝试解释其中的任何内容
    • (?<=...)这就是所谓的后向断言。它表示我们想要"username":"在其他内容之前进行匹配,但不将其包含在输出中
    • [^"]*意思是“尽可能多的不是 的字符"。它可以再次细分:
    • [..]是一个字符类。此时允许在方括号之间放置任何字符。除非...
    • ^"当您使用插入符号^作为字符类中的第一个字符时,这意味着不是以下任意字符
    • *[^"]表示 0 个或多个前面的项目(在本例中是 的整体)。

通过管道将sort用户名按字母顺序排序,带有选项-u意味着“仅唯一项目”,即没有重复项。

注意:所有这些都假设我们匹配的模式不会出现在文件中的其他任何位置(这似乎不太可能),或者 JSON 本身的损坏不会导致匹配失败(这可能是,我不确定您的文件以何种方式损坏)。

编辑: 由于grep经常抱怨行太长,并且由于某种原因sed -e 's/,/,\n/'也无法真正工作,因此该split命令用于将文件分解为更易于管理的块。

答案2

您似乎有很长的 JSON 记录会中断grep -P,这是一个替代解决方案:

grep -o '"username":"[^"]*' users.json \
| cut -d '"' -f 4 \
| uniq \
| sort -u \
> usernames.txt

在这里,grep提取完整的“用户名:值”字段,cut提取值并uniq | sort -u使用户名唯一。

uniq没有必要。对于 3GB 的文件,我希望得到数百万个名字的列表,其中有很多连续的重复项。看似无用的东西uniq |减轻了sort部分工作的负担,并且可能会让工作进展得更快。不然就不会痛了

相关内容