2012-04-16 104 views
1

我有大的制表符分隔两列文本文件中,就像这样:AWK笛卡尔积

... 
"001R_FRG3G" "81941549; 47060116; 49237298" 
"002L_FRG3G" "49237299; 47060117; 81941548" 
"002R_IIV3" "106073503; 123808694; 109287880" 
... 

正如你看到的第二列不包含原子值。这就是为什么我想“正常化”这个文件有类似的东西:

... 
"001R_FRG3G" "81941549" 
"001R_FRG3G" "47060116" 
"001R_FRG3G" "49237298" 
"002L_FRG3G" "49237299" 
"002L_FRG3G" "47060117" 
"002L_FRG3G" "81941548" 
"002R_IIV3" "106073503" 
"002R_IIV3" "123808694" 
"002R_IIV3" "109287880" 
... 

任何人都知道如何有效地做到这一点?

回答

1

的Perl:

perl -lne ' 
s/[";]//g; 
($a, @b) = split; 
print qq("$a" "$_") for @b; 
' FILE 
+0

在我的情况下,这是所有提供的解决方案中最快的一个(仅)两个实际工作... – mnowotka 2012-04-17 22:08:55

1
awk '{for (i=2; i<=NF; i++) {gsub(/[";]/, "", $i); printf "%s%s\"%s\"", $1, OFS, $i; printf "%s", "\n"}}' inputfile 

对于$1后的每个字段,条引号和分号,然后打印$1随后通过引号所包围的领域的内容。为输入文件中的每一行执行此操作。

+0

不为我工作。即使不去掉qoutes。 – mnowotka 2012-04-18 10:59:34

+0

@mnowotka:您在问题中显示的所需输出包括每个数据项的引号。我的脚本去掉了引号并将它们添加回来,以便根据请求输出结果,正如我在我的回答中所述。它究竟如何不适合你? – 2012-04-18 11:12:08

0

这可能会为你(GNU AWK)工作:

awk '{while(/;/) $0=gensub(/^((.*[ \t]").*);[ \t]*/,"\\1\"\n\\2",1)};1' file 
"001R_FRG3G" "81941549" 
"001R_FRG3G" "47060116" 
"001R_FRG3G" "49237298" 
"002L_FRG3G" "49237299" 
"002L_FRG3G" "47060117" 
"002L_FRG3G" "81941548" 
"002R_IIV3" "106073503" 
"002R_IIV3" "123808694" 
"002R_IIV3" "109287880" 

,或者它不是awk的,但它优雅地解决了这个问题。

sed -i ':a;s/\(\(.*\s"\).*\);\s*/\1"\n\2/;ta' file 
"001R_FRG3G" "81941549" 
"001R_FRG3G" "47060116" 
"001R_FRG3G" "49237298" 
"002L_FRG3G" "49237299" 
"002L_FRG3G" "47060117" 
"002L_FRG3G" "81941548" 
"002R_IIV3" "106073503" 
"002R_IIV3" "123808694" 
"002R_IIV3" "109287880"