对于Scala中的文本文件,`X1:Y1 | X2:Y2..`转换为`X1 Y1..`

时间:2018-01-30 21:04:41

标签: scala apache-spark

我有一个包含以下数据的文本文件

X1:Y1|X2:Y2|X3:Y3|X4:Y4|X5:Y5

我想实现此输出

X1 Y1
X2 Y2
X3 Y3
X4 Y4
X5 Y5

现在我一直试图以这种方式实现,但无法获得

我尝试过以下代码:

scala> val input = sc.textFile("/home/bhaskar/Desktop/log.txt")
input: org.apache.spark.rdd.RDD[String] = /home/bhaskar/Desktop/log.txt MapPartitionsRDD[1] at textFile at <console>:24

scala> val rdd1 = input.flatMap(line => line.split('|'))
rdd1: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[23] at flatMap at <console>:26

得到以下不同的输出:

scala> for(x <- rdd1){println(x)}
X1:Y1
X2:Y2
X3:Y3
X4:Y4
X5:Y5

scala> for(x <- rdd1){println(x.split(":"))}
[Ljava.lang.String;@3ce3bfde
[Ljava.lang.String;@7752bb7c
[Ljava.lang.String;@3af05705
[Ljava.lang.String;@2296f59c
[Ljava.lang.String;@3aaa35f

scala> for(x <- rdd1){println(x.split(":").toString())}
[Ljava.lang.String;@36154dc9
[Ljava.lang.String;@586b85e5
[Ljava.lang.String;@1436d0d6
[Ljava.lang.String;@21295bb6
[Ljava.lang.String;@3dce215f

4 个答案:

答案 0 :(得分:1)

您只需将所有冒号":"替换为空格" ",将所有竖线"|"替换为换行"\n"即可。请尝试以下代码

val str = "X1:Y1|X2:Y2|X3:Y3|X4:Y4|X5:Y5"

val foramttedStr = str.replaceAll(":"," ").replaceAll("\\|","\n")

print(foramttedStr)

//output
// X1 Y1
// X2 Y2
// X3 Y3
// X4 Y4
// X5 Y5

Spark程序中使用类似的功能,您可以使用以下代码

val rdd1: RDD[String] = input.map(line => line.replaceAll(":"," ").replaceAll("\\|","\n"))

rdd1.foreach(println(_))

它将产生与上面相同的输出。

答案 1 :(得分:0)

input.flatMap(line => line.split('|'))
  .foreach(line => println(line.split(":").mkString(" ")))

您正在尝试打印出String的列表 - 而不是事先连接它的元素。

答案 2 :(得分:0)

最直接的方法是只替换字符:

input.replace(":", " ").replace("|", "\n")

但是,在我看来,总是建议将输入转换为适当的数据结构(在这种情况下,我选择Seq[(String, String)]但当然是YMMV):

val parsed: Seq[(String, String)] = input.
  split('|').               // split by '|'
  iterator.                 // avoid creating intermediate collections
  map(s => s.split(':')).   // split each "line" by ':'
  map(a => a(0) -> a(1)).   // transform each "line" from an array to a pair
  toSeq                     // collect into the resulting sequence

这样我们就可以更自由地使用它了。

鉴于这种结构,现在打印您最初想要的东西非常简单:

for ((a, b) <- parsed) {
  println(s"$a $b")
}

答案 3 :(得分:0)

您的代码x.split('|')正在生成一个打印为[Ljava.lang.String;@36154dc9

的Java数组

关于打印Java数组有很多Google或SO答案,但在Scala中你可以这样做;

scala> for(x <- rdd1) { println(x.split(":").mkString(" ")) }