0

我们最近收到了一个要提取的文件,这个文件是PSV格式的,但是所有的字段左右都加了额外的字符$~$,所以整个PSV如下:

$~$Field1$~$|$~$Field2$~$|$~$Field3$~$

$~$Data1$~$|$~$Data2$~$|$~$Data3$~$

$~$Data4$~$|$~$Data5$~$|$~$Data6$~$

$~$Data7$~$|$~$Data8$~$|$~$Data9$~$

$~$Data10$~$|$~$Data11$~$|$~$Data12$~$ .....

文件中有 1 亿行。

修剪这些填充物以使其成为标准 PSV 的最佳方法是什么?

非常感谢您,任何建议/分享在这里表示赞赏。

更新:

数据从 SFTP 接收,并由 IT 数据支持(Unix 管理员)上传到 Hadoop,我们只能访问 Hadoop 集群,但如果数据支持很容易,也许我可以说服他们做预处理。谢谢。

4

3 回答 3

0

这是一个纯 Spark 解决方案。可能有更好的解决方案。

var df = spark.read.option("delimiter", "|").csv(filePath)
val replace = (value: String, find: String, replace: String) => value.replace(find, replace)
val replaceUdf = udf(replace)
df.select(
       df.columns.map(c => replaceUdf(col(c), lit("$~$"), lit("")).alias(c)): _*)
  .show

更新:您不能在 2.3.0 中使用$~$asquote选项或$~$|$~$用作 a delimiter,因为这些选项只接受单个字符。

于 2019-02-08T08:51:51.223 回答
0

使用 regexp_replace 和 foldLeft 更新所有列。看一下这个

scala> val df = Seq(("$~$Data1$~$","$~$Data2$~$","$~$Data3$~$"), ("$~$Data4$~$","$~$Data5$~$","$~$Data6$~$"), ("$~$Data7$~$","$~$Data8$~$","$~$Data9$~$"),("$~$Data10$~$","$~$Data11$~$","$~$Data12$~$")).toDF("Field1","field2","field3")
df: org.apache.spark.sql.DataFrame = [Field1: string, field2: string ... 1 more field]

scala> df.show(false)
+------------+------------+------------+
|Field1      |field2      |field3      |
+------------+------------+------------+
|$~$Data1$~$ |$~$Data2$~$ |$~$Data3$~$ |
|$~$Data4$~$ |$~$Data5$~$ |$~$Data6$~$ |
|$~$Data7$~$ |$~$Data8$~$ |$~$Data9$~$ |
|$~$Data10$~$|$~$Data11$~$|$~$Data12$~$|
+------------+------------+------------+


scala> val df2 = df.columns.foldLeft(df) { (acc,x) => acc.withColumn(x,regexp_replace(col(x),"""^\$~\$|\$~\$$""","")) }
df2: org.apache.spark.sql.DataFrame = [Field1: string, field2: string ... 1 more field]

scala> df2.show(false)
+------+------+------+
|Field1|field2|field3|
+------+------+------+
|Data1 |Data2 |Data3 |
|Data4 |Data5 |Data6 |
|Data7 |Data8 |Data9 |
|Data10|Data11|Data12|
+------+------+------+


scala>
于 2019-02-09T15:13:27.400 回答
0

tr可能是更快的解决方案。请注意,您可以通过管道传输任何字符串,因此在这种情况下,我cat在磁盘上输入文件,但这也可以是来自 sftp 的文件流。

~/Desktop/test $ cat data.txt
$~$Field1$~$|$~$Field2$~$|$~$Field3$~$

$~$Data1$~$|$~$Data2$~$|$~$Data3$~$

$~$Data4$~$|$~$Data5$~$|$~$Data6$~$

$~$Data7$~$|$~$Data8$~$|$~$Data9$~$

# the '>' will open a new file for writing

~/Desktop/test $ cat data.txt | tr -d \$~\$ > output.psv

# see the results here
~/Desktop/test $ cat output.psv 
Field1|Field2|Field3

Data1|Data2|Data3

Data4|Data5|Data6

Data7|Data8|Data9

示例:https ://shapeshed.com/unix-tr/#what-is-the-tr-command-in-unix

于 2019-02-11T15:58:14.277 回答