Talend - 使用动态列数转置输入文件

时间:2014-08-14 15:17:12

标签: csv talend unpivot dynamic-columns data-mapping

我有一个非常棘手的情况,并且尚未使用Talend提出我自己的解决方案。我有一个输入csv文件,它具有动态列数,需要转置此文件以创建所需的输出文件。输入文件如下所示:

ID1 | Units1 | Count | Val1a | Val2a | Val3a | Val1b | Val2b | Val3b | Val1c | Val2c | Val3c
ID2 | Units2 | Count | Val1d | Val2d | Val3d | Val1e | Val2e | Val3e

正如你所看到的,Val在每一行都是三连音,我需要三胞胎才能保持在一起。 “计数”列包含在该行上找到的三元组数,因为每行都是动态的。我需要的最终输出是:

ID1 | Units1 | Val1a | Val2a | Val3a
ID1 | Units1 | Val1b | Val2b | Val3b
ID1 | Units1 | Val1c | Val2c | Val3c
ID2 | Units2 | Val1d | Val2d | Val3d 
ID2 | Units2 | Val1e | Val2e | Val3e

我尝试过旋转和取消行,但这不允许我将三元组保持在一起。我是否可以通过Java脚本发送输入文件,我解析文件并以此格式输出到csv文件?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

你应该能够在tJavaRow中编写一个自定义的Java代码,它应该根据你的需要解析出来。

您可能希望使用tFileInputRaw将原始源作为原始输入读取,这样您就可以解析tJavaRow组件中的所有内容。您需要将输出模式添加到tJavaRow,其中包含id,unit,value1,value2和value3的列。

因为您需要将行分解为多行,所以最好将1a,1b,1c和1d等值连接在一起,然后可以使用tNormalize组件进一步分成单独的行。会根据需要打破这一行。

在我的脑海中,tJavaRow组件中的代码可能类似于:

// First we split the data on the delimiter of the file, assuming comma separated for now
String[] splitData = inputrow.content.split(",");
// Initialise the three value strings
String value1 = ""
String value2 = ""
String value3 = ""
for (int i = 0; i < splitData.length; i++) {
    if (i == 1) {
        // id field is the first field
        String id = splitData[i];
    } else if (i == 2) {
        unit field is the second field
        String unit = splitData[i];
    } else if (i == 3) {
        // Don't need to do anything with the count data
    } else if (i % 3 == 1) {
        // value1 fields are 4, 7, 10 etc so modulo 3 == 1
        if (value1.length == 0) {
            value1 + splitData[i];
        } else {
            // if the value field isn't empty (ie. for val1b) then we need to add a delimiter for further processing
            value1 + "|" + splitData[i];
        }
    } else if (i % 3 == 1) {
        if (value2.length == 0) {
            value2 + splitData[i];
        } else {
            value2 + "|" + splitData[i];
        }
    } else if (i % 3 == 3) {
        if (value3.length == 0) {
            value3 + splitData[i];
        } else {
            value3 + "|" + splitData[i];
        }
    }
}

// Finally we then assign these strings to their output schema columns
output_row.id = id;
output_row.unit = unit;
output_row.value1 = value1;
output_row.value2 = value2;
output_row.value3 = value3;

如果您的任何字段的内容都包含逗号(或您的文件具有的任何分隔符),您将遇到一些问题,因为您需要制作一个更复杂的解析方法,允许引用的字段数据。

从这里你只需要连接tNormalize组件并将它拆分为|字符(或者您选择的任何字符,它应该是您的源数据中找不到的字符)。您可能需要执行此操作三次才能获得所需的输出(因为您有三列要标准化)。