提问人:Alexandra 提问时间:10/23/2023 最后编辑:Charles DuffyAlexandra 更新时间:10/24/2023 访问量:59
过滤 TTL 文件过大,rdflib 无法解析内存中的文件,否则
Filter a TTL file too large for rdflib to parse in-memory otherwise
问:
我正在处理一个 20 GB 的大型 ttl 文件,我尝试使用 rdflib 读入,但我收到错误
killed
为了避免这种情况,我正在尝试使用 grep 命令从该文件创建一个较小的文件。
示例数据为 yagoTransitiveType.ttl;开头包含如下所示的行:
@base <http://yago-knowledge.org/resource/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<1908_St._Louis_Browns_season> rdf:type <wikicat_St._Louis_Browns_seasons> .
<1908_St._Louis_Browns_season> rdf:type <wordnet_abstraction_100002137> .
<A1086_road> rdf:type <wikicat_Roads_in_the_United_Kingdom> .
<A1086_road> rdf:type <wordnet_artifact_100021939> .
我只想保留顶部标题中的行,或包含 .wordnet_
到目前为止,我尝试过的是:
grep "wordnet_" yagoTransitiveType.ttl >wordnet_yagoTransitiveType.ttl
问题是该文件没有像 yago: 和其他那样读取初始前缀,因此 rdflib 无法解析 ttl 文件。
import rdflib
g = rdflib.Graph()
g.parse('yagoTransitiveType.ttl', format='ttl')
如何通过在运行 grep 命令或任何其他方式后添加 10 行来解决问题?
答:
1赞
Charles Duffy
10/23/2023
#1
据我了解,您希望保留以下两种类型的数据之一:
- 不包含的数据
rdf:type
- 同时包含 和 的数据(按此顺序)
rdf:type
wordnet_
效率较低(因为它读取输入文件两次),这可能如下所示:
{
grep -v rdf:type yagoTransitiveType.ttl
grep -Ee 'rdf:type.*wordnet' yagoTransitiveType.ttl
} >filtered.ttl
...或者,以稳健性换取效率(读取文件两次,但在第一次通过时只读取前 10 行 -- 但取决于你是否提供要保留的行数的准确计数):
keep_count=10
{
head -n "$keep_count" yagoTransitiveType.ttl
grep -Ee 'rdf:type.*wordnet' yagoTransitiveType.ttl
} >filtered.ttl
请注意,在上述两个工具中,我们提供了两次输入文件名,因此第二个工具从文件的开头重新开始,而不是共享输入文件句柄并指望第一个工具在文件中的正确位置读取光标。我们稍后会看到替代方案。
作为更有效的替代方法(仅读取输入文件一次并使用同一工具执行这两个操作):
awk '
! /rdf:type/ { print; next }
/rdf:type/ && /wordnet_/ { print }
' <yagoTransitiveType.ttl >filtered.ttl
awk
是一种功能齐全的编程语言;因此,它可以执行任意操作,而 grep 只对单个行进行正则表达式匹配。
如果您真的只想复制前 10 行未过滤,然后使用 grep 过滤其余行,则如下所示:
keep_count=10
{
for ((i=0; i<keep_count; i++)); do
IFS= read -r line && printf '%s\n' "$line"
done
grep -e wordnet_
} <yagoTransitiveType.ttl >filtered.ttl
所有这些都将生成一个 .filtered.ttl
评论
0赞
Ed Morton
10/24/2023
您不需要开始 awk 脚本的第二行,因为只有当从上面的行是 false 时,才能到达该行。当然,你可以把它改写成。/rdf:type/ &&
!/rdf:type/
awk '/wordnet_/ || !/rdf:type/'
0赞
Ed Morton
10/24/2023
#2
这是你想做的吗?
$ grep -E '^@|wordnet_' yagoTransitiveType.ttl
@base <http://yago-knowledge.org/resource/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<1908_St._Louis_Browns_season> rdf:type <wordnet_abstraction_100002137> .
<A1086_road> rdf:type <wordnet_artifact_100021939> .
评论