我有一个巨大的数据集,例如15 - 20 GB,它是一个制表符分隔文件。虽然我可以在Python或SQL中执行此操作,但在Shell脚本中完成它以避免移动csv文件会更容易和简单
说,例如,采用管道分隔文件输入:
----------------------------------------
Col1 | Col2 | Col3 | Col4 | Col5 | Col6
----------------------------------------
A | H1 | 123 | abcd | a1 | b1
----------------------------------------
B | H1 | 124 | abcd | a2 | b1
----------------------------------------
C | H2 | 127 | abd | a3 | b1
----------------------------------------
D | H1 | 128 | acd | a4 | b1
----------------------------------------
SQL查询看起来像
SELECT Col1,Col4,Col5,Col6 FROM WHERE col2 ='H1'
输出:
--------------------------
Col1 | Col4 | Col5 | Col6
--------------------------
A | abcd | a1 | b1
--------------------------
B | abcd | a2 | b1
--------------------------
D | acd | a4 | b1
--------------------------
然后,我只需要接受它的Col4来做一些字符串解析并在下面输出 OutputFile1:
--------------------------------
Col1 | Col4 | Col5 | Col6 | New1
--------------------------------
A | abcd | a1 | b1 | a,b,c,d
--------------------------------
B | abcd | a2 | b1 | a,b,c,d
--------------------------------
D | acd | a4 | b1 | a,c,d
--------------------------------
Col4是一个URL。我需要解析URL参数。请参阅问题 - How to parse URL params in shell script
我想知道我是否有另一个文件
File2:
--------------
ColA | ColB |
--------------
A | abcd |
--------------
B | abcd |
--------------
D | qst |
--------------
我需要为ColB生成类似的解析输出。
OutputFile2:
--------------
ColA | ColB | New1
--------------
A | abcd | a,b,c,d
--------------
B | abcd | a,b,c,d
--------------
D | qst | q,s,t
--------------
合并OutputFile1和OutputFile2的SQL查询将在
上进行内连接OutputFile1.Col1 = OutputFile2.ColA和OutputFile1.New1 = OutputFile2.New1
最终输出:
--------------------------------
Col1 | Col4 | Col5 | Col6 | New1
--------------------------------
A | abcd | a1 | b1 | a,b,c,d
--------------------------------
B | abcd | a2 | b1 | a,b,c,d
--------------------------------
请分享建议以实施相同的目标。
主要限制因素是文件的大小。
由于
答案 0 :(得分:3)
在http://open-innovation.alcatel-lucent.com/projects/unity/,UNIX有一个非常简单的数据库管理程序,名为“unity”。在统一中,您有两个主要文件:
这些都是简单的文本文件,您可以使用您喜欢的任何编辑器进行编辑(或者它拥有自己的数据库感知编辑器,名为uedit)。
对于foo中的每一列,Dfoo都会有一行描述foo中该列中出现的数据的属性,并且它是下一列中的分隔符。
foo会有数据。
已经有一段时间了,因为我在raw中使用了unity(我有在幕后使用它的脚本)但是对于你在上面显示的第一个表:
----------------------------------------
Col1 | Col2 | Col3 | Col4 | Col5 | Col6
----------------------------------------
A | H1 | 123 | abcd | a1 | b1
----------------------------------------
B | H1 | 124 | abcd | a2 | b1
----------------------------------------
C | H2 | 127 | abd | a3 | b1
----------------------------------------
D | H1 | 128 | acd | a4 | b1
----------------------------------------
描述符文件(Dfoo)将类似于:
Col1 | 5c
Col2 | 6c
Col3 | 6c
Col4 | 6c
Col5 | 6c
Col6 \n 6c
,数据文件(foo)为:
A|H1|123|abcd|a1|b1
B|H1|124|abcd|a2|b1
C|H2|127|abd|a3|b1
D|H1|128|acd|a4|b1
然后您可以运行统一命令,如:
uprint -d- foo
打印表格,其行由下划线和描述符文件中指定宽度的单元格分隔(例如,6c = 6个字符居中,而6r = 6个字符右对齐)。
uselect Col2 from foo where Col3 leq abd
从列Col2中选择值,其中Col3中的对应值是词汇式EQual,字符串为“abd”。
有一些统一命令可以让你进行连接,合并,插入,删除等等 - 基本上你希望能够对关系数据库做什么,但它只是基于简单的文本文件。
在统一中,您可以在每列之间指定不同的分隔符,但如果所有分隔符都相同(除了最后一个将是'\ n'),那么您也可以使用awk在文件上运行awk脚本 - F带分隔符。
你可以看到的其他几个工具集可能更容易安装,但可能没有Unity统一的功能(自20世纪70年代以来一直存在!)将是recutils(来自GNU)和csvDB所以你的完整的家庭作业/研究清单是:
请注意,recutils具有rec2csv和csv2rec工具,用于在recutils和CSV格式之间进行转换。
答案 1 :(得分:2)
对于管道分隔文件:
awk '$2=="H1"{y="";x=$4;for(i=1;i<=length($4);i++)y=y?y","substr(x,i,1):substr(x,i,1);print $1,$4,$5,$6,y;}' FS="|" OFS="|" file
对于制表符分隔文件,请将FS保留为空:
awk '$2=="H1"{y="";x=$4;for(i=1;i<=length($4);i++)y=y?y","substr(x,i,1):substr(x,i,1);print $1,$4,$5,$6,y;}' OFS="\t" file