我的任务是解析一个非常大的单行文本文件并将其放入数据库中。该文件包含大量文本数据(48 GB),并以以下格式提供给我:
col1*#(%&col2*#(%&col3*#(%&col4*#(%&col5*#(%&col1*#(%&col2*#(%&col3*#(%&col4...
因此,该文件中的分隔符是“*#(%&”,这些列基本上在一行中从 col1-col5 循环。
我的目标是尝试将这些转化为记录格式,即:
col1*#(%&col2*#(%&col3*#(%&col4*#(%&col5*#(%&
col1*#(%&col2*#(%&col3*#(%&col4*#(%&col5*#(%&
col1*#(%&col2*#(%&col3*#(%&col4*#(%&col5*#(%&
所以我想在每 5 个 '*#(%&' 之后添加一个 '\n'。我环顾四周,发现一个方便的 sed 命令可以做到这一点事物:
sed -r 's/([^\*#\(%\&|]*\*#\(%\&){5}/&\n/g'
然而,在大多数情况下,这是有效的,因为 col4 是一个巨大的文本字段,我注意到对于 col 包含任何单个字符的记录'#(%&' 即'#',计数似乎重置了,并且它的行为不符合我想要的方式。有没有办法调整或避免这种情况发生?我只想要一个新行,只有当 ' 的确切模式时#(%&' 出现。
答案1
使用 GNU awk
,您可以执行以下操作:
gawk -v RS='\\*#\\(%&' -v ORS= '{print $0 RT};NR%5 == 0{printf "\n"}'
使用sed
(但要注意某些sed
实现对行的大小有下限):
sed 's/*#(%&/&\
/5;P;D'
答案2
perl -F'\*#\(%&' -lane 'print join "*#(%&", splice @F, 0, 5 while @F'
在职的:
° Split on the string `*#(%&` it is stored in the array @F.
° Then, while the array still has elements in it, pluck out the leading 5, or whatever are left in the last gasp, and join these with the same string they were split on. And this is printed to stdout followed by a newline which is ensured by the `-l` option.