2015-09-15 4 views
1

Я пытаюсь разбить строку на массив, используя регулярное выражение. Моя строка содержит журнал apache, и я ищу разбивку с использованием sql.SparkSQL split using Regex

Я пробовал функцию split и array, но ничего.

 
Select split('10.10.10.10 - - [08/Sep/2015:00:00:03 +0000] "GET /index.html HTTP/1.1" 206 - - "Apache-HttpClient" -', '^([^ ]+) ([^ ]+) ([^ ]+) \[([^\]]+)\] "([^"]+)" \d+ - - "([^"]+)".*') 
; 

Я ожидаю, что массив с 6 элементами

Благодарности

+0

Я бы рекомендовал создать таблицу улей, как HTTP: //www.dowdandassociates. com/blog/content/howto-use-hive-with-apache-logs/затем скопируйте проанализированные данные в таблицу Parquet. –

ответ

2

SPLIT функция, как вы можете догадаться, расщепляет строку по шаблону. Поскольку строка шаблона, которую вы предоставляете, соответствует целому вводу, ничего не вернуть. Следовательно, пустой массив.

import org.apache.spark.sql.functions.{regexp_extract, array} 

val pattern = """^([^ ]+) ([^ ]+) ([^ ]+) \[([^\]]+)\] "([^"]+)" \d+ - - "([^"]+)".*""" 

val df = sc.parallelize(Seq((
    1L, """10.10.10.10 - - [08/Sep/2015:00:00:03 +0000] "GET /index.html HTTP/1.1" 206 - - "Apache-HttpClient" -""" 
))).toDF("id", "log") 

Что вам нужно здесь regex_extract:

val exprs = (1 to 6).map(i => regexp_extract($"log", pattern, i).alias(s"_$i")) 

df.select(exprs:_*).show 
// +-----------+---+---+--------------------+--------------------+-----------------+ 
// |   _1| _2| _3|     _4|     _5|    _6| 
// +-----------+---+---+--------------------+--------------------+-----------------+ 
// |10.10.10.10| -| -|08/Sep/2015:00:00...|GET /index.html H...|Apache-HttpClient| 
// +-----------+---+---+--------------------+--------------------+-----------------+ 

или например UDF:

val extractFromLog = udf({ 
    val ip = new Regex(pattern) 
    (s: String) => s match { 
    // Lets ignore some fields for simplicity 
    case ip(ip, _, _, ts, request, client) => 
     Some(Array(ip, ts, request, client)) 
    case _ => None 
    } 
}) 

df.select(extractFromLog($"log"))