使用awk重新格式化数据

时间:2018-06-29 17:43:53

标签: linux awk sed grep

我有一个数据集,其中包含UUID行,后跟位置和事务ID。 UUID用分号(';')分隔,而事务则用制表符分隔,如下所示:

01234;LOC_1=ABC    LOC_1=BCD    LOC_2=CDE
56789;LOC_2=DEF    LOC_3=EFG

我事先知道所有位置代码。我想做的就是将这些数据转换成可以加载到SQL / Postgres中进行分析的格式,如下所示:

01234;LOC_1=ABC
01234;LOC_1=BCD
01234;LOC_2=CDE
56789;LOC_2=DEF
56789;LOC_3=EFG

我敢肯定,我可以使用awk(或类似方法)轻松地做到这一点,方法是从文件(例如LOC_1)中查找位置ID,并匹配任何位置ID实例,然后将其打印在UUID旁边。我还无法解决问题,非常感谢您的帮助!

我的位置文件名为location,我的数据集为data。请注意,我可以编辑原始文件或将结果写到新文件中,两者都可以。

5 个答案:

答案 0 :(得分:5)

不使用split的awk:使用分号标签作为字段分隔符

awk -F'[;\t]' -v OFS=';' '{for (i=2; i<=NF; i++) print $1,$i}' file

答案 1 :(得分:3)

我认为您不需要与已知位置列表进行匹配;您应该能够随行打印每行:

$ awk '{print $1; split($1,a,";"); for (i=2; i<=NF; ++i) print a[1] ";" $i}' file
01234;LOC_1=ABC
01234;LOC_1=BCD
01234;LOC_2=CDE
56789;LOC_2=DEF
56789;LOC_3=EFG

答案 2 :(得分:2)

您评论知道位置和映射文件后,使我怀疑您的示例似乎执行的操作不完全是所要询问的内容-但似乎您想重新格式化每组制表符分隔的{{1 }}值排成一行,其UUID位于前面。

如果是这样,就可以解决问题:

LOC=

给出:

awk ' BEGIN {OFS=FS=";"} {split($2,locs,"\t"); for (n in locs) { print $1,locs[n]}}' 

然后:

$ cat -A data.txt
 01234;LOC_1=ABC^ILOC_1=BCD^ILOC_2=CDE$
 56789;LOC_2=DEF^ILOC_3=EFG$

$ awk ' BEGIN {OFS=FS=";"} {split($2,locs,"\t"); for (n in locs) { print $1,locs[n]}}' data.txt 01234;LOC_1=ABC 01234;LOC_1=BCD 01234;LOC_2=CDE 56789;LOC_2=DEF 56789;LOC_3=EFG 块将输入和输出定界符设置为;。

然后,对于每一行,我们通过-BEGIN {OFS=FS=";"}

将第二个字段拆分为一个名为locs的数组,在选项卡上拆分

然后循环遍历打印UUID和每个loc值的位置-split($2,locs,"\t")

答案 3 :(得分:2)

不进行循环或不进行如下拆分的情况如何(考虑到Input_file仅与所示示例相同)

awk 'BEGIN{FS=OFS=";"}{gsub(/[[:space:]]+/,"\n"$1 OFS)} 1'  Input_file

答案 4 :(得分:0)

这可能对您有用(GNU sed):

sed -r 's/((.*;)\S+)\s+(\S+)/\1\n\2\3/;P;D' file

反复用换行符替换位置之间的空白,然后用UUID和;替换,打印/删除每行显示的内容。