NiFi替换文本过程,尝试用属性值替换第n列最终出错

时间:2017-11-01 17:50:49

标签: apache-nifi

使用替换文本处理器以逗号(,)作为分隔符替换44列文件中的几列。

一个流文件只有一行,包含44个字段。

在替换文本处理器中,

enter image description here

我需要使用属性更改流文件中的第3列。 所以我把它分成4组,用一个属性替换第二组的数据。

如果我这样做,处理器会挂起。如何用特定属性或字符串替换第n列?

2 个答案:

答案 0 :(得分:2)

您使用的是什么版本的NiFi?从NiFi 1.3.0开始,您可以使用“记录感知”处理器,例如UpdateRecord。您可以通过从标题行推断字符串字段或为字段提供自己的Avro架构来配置CSVReader。假设所需列/字段的名称是“fname”。在UpdateRecord中,您可以将替换策略设置为“Literal”,并添加名为“/ fname”的用户定义属性,其值为“$ {filename}”。这应该允许您就地更新CSV文件,而不必分割行或处理正则表达式来解析行。

答案 1 :(得分:1)

注意:如果使用Apache NiFi 1.3.0+版本,Matt的方式会更好

我的建议是使用ExecuteScript处理器并使用Groovy来执行此操作。我相信你最终可以制作一个符合你要求的正则表达式,但正如你所说,性能不会很好,如果有更大的流文件,你可能会崩溃堆。

在Groovy(或Python / Ruby / etc。)中,这将是一个简单的字符串替换操作,如下所示:

import org.apache.commons.io.IOUtils
import java.nio.charset.*

def flowFile = session.get()
if(!flowFile) return

flowFile = session.write(flowFile, {inputStream, outputStream ->
    def elements = IOUtils.toString(inputStream, StandardCharsets.UTF_8).split(",")
    // Rather than hardcoding, you could make the column index also read from a flowfile attribute to make this more generic
    elements[2] = flowfile.getAttribute("myAttributeName")
    def outputString = elements.join(",")

   outputStream.write(outputString.getBytes(StandardCharsets.UTF_8))
} as StreamCallback)

session.transfer(flowFile, REL_SUCCESS)