Таблица куста, разделенная запятой и несколькими пробелами

У меня есть аналогичный вопрос здесь: Источник таблицы Hive, разделенный несколькими пробелы

Мои данные выглядят так:

AL, 01, 2016010700,   , BEST,   0, 266N,  753W
AL, 01, 2016010706,   , BEST,   0, 276N,  747W
AL, 01, 2016010712,   , BEST,   0, 287N,  738W
AL, 01, 2016010712,   , BEST,   0, 287N,  738W

Это означает, что мой разделитель столбцов - это «запятая плюс переменное количество пробелов».

Я попытался просто изменить field.delim, добавив эту запятую в регулярное выражение, но это не сработало. В результате все данные помещаются в первый столбец (basin), а все остальные столбцы равны NULL.

CREATE EXTERNAL TABLE IF NOT EXISTS default.myTable1
(
   basin string
  ,cy string
  ,yyyymmddhh int
  ,technum_min string
  ,tech string
  ,tau string
  ,lat_n_s string
  ,lon_e_w string 
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe' 
WITH SERDEPROPERTIES ("field.delim"=",\\s+")
LOCATION '/data';

Я использую HDP 2.5 (Hive 1.2.1).

Спасибо за любую помощь и предложения.


person BlueElephant    schedule 27.07.2017    source источник


Ответы (2)


У нас есть два подхода к решению вашей проблемы. создать таблицу 'rawTbl', используя приведенную ниже опцию

ROW FORMAT DELIMITED FIELDS TERMINATED BY ','

и используйте trim() для удаления пробела

Insert into baseTbl select trim(basin), trim(cy),...., from rawTbl

ИЛИ вы можете использовать регулярное выражение

Я обновил ответ регулярным выражением, которое отделяет файл ввода текста, состоящий из запрошенных полей. Regex содержит 7 групп регулярных выражений, которые захватывают запрошенное поле в каждой строке.

CREATE EXTERNAL TABlE tableex(basin string
  ,cy string
  ,yyyymmddhh int
  ,technum_min string
  ,tech string
  ,tau string
  ,lat_n_s string
  ,lon_e_w string ) 
ROW FORMAT 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  "input.regex" = '^([A-Za-z]{2}),\s+(\d{2}),\s(\d{10}),\s+,\s([A-Z]{4}),\s+(\d{1}),\s+(\d{3}[A-Z]{1}),\s+(\d+[A-Z]{1})'
)
LOCATION '/data';
person Manish Saraf Bhardwaj    schedule 27.07.2017
comment
input.regex определяет выражения столбцов, а не разделитель. - person David דודו Markovitz; 27.07.2017
comment
Да, именно поэтому я хотел попробовать MultiDelimitSerDe, как указано в связанном вопросе. К сожалению, использование RegexSerDe не работает: ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' WITH SERDEPROPERTIES ("input.regex" = ",\s+") Я также пробовал использовать двойную обратную косую черту: ,\\s+. Он всегда дает мне все столбцы со значениями NULL. - person BlueElephant; 27.07.2017
comment
Привет :-) Лучше, но я бы использовал что-то вроде \s*(\S*?), вместо фиксированной длины. - person David דודו Markovitz; 27.07.2017
comment
У меня есть один обходной путь: (1) создать таблицу с ПОЛЯМИ, РАЗДЕЛЕННЫМИ ФОРМАТОМ СТРОКИ, ЗАКРЫВАЕМЫМИ ',' (2) Вставить в baseTbl select trim(basin), trim(cy),...., from rawTbl - person Manish Saraf Bhardwaj; 27.07.2017
comment
Я проголосовал за это, но только за первую часть решения. Мне было бы очень грустно, если бы я получил второй и должен был обновить его или устранить неполадки. - person Dennis Jaheruddin; 27.07.2017
comment
@DuduMarkovitz: Каков ваш отзыв? - person Manish Saraf Bhardwaj; 27.07.2017
comment
Я уже прокомментировал (Лучше, но...), я что-то упустил? - person David דודו Markovitz; 27.07.2017
comment
@BlueElephant: пожалуйста, сделайте ответ правильным, если он вам подходит. - person Manish Saraf Bhardwaj; 28.07.2017
comment
@ManishSarafBhardwaj: Спасибо за ответ. Подход INSERT INTO работает с файлом. В качестве альтернативы мы могли бы просто поместить представление поверх него с операторами trim. Однако второе решение с регулярным выражением у меня не работает. В моей версии Hive мне нужно написать ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' => ключевое слово SERDE необходимо в моей версии Hive. Но в целом я всегда получаю все столбцы со значениями NULL. Какую версию Hive вы используете? - person BlueElephant; 28.07.2017
comment
@DuduMarkovitz: я пробовал что-то похожее с "field.delim"=",\\s+" (и некоторыми другими вариантами) ... ваше регулярное выражение кажется мне интересным ... но я не уверен, как его интерпретировать ... можете ли вы немного поподробнее об этом? Конечно, иметь элегантное регулярное выражение для синтаксического анализа было бы идеально. - person BlueElephant; 28.07.2017
comment
1) field.delim — это одиночный символ, а не регулярное выражение 2) регулярное выражение означает последовательность из нуля или более пробелов, а не последовательность из нуля или более не пробелов - person David דודו Markovitz; 28.07.2017

как насчет этого

(\S+),\s+(\S+),\s(\S+),\s+,\s(\S+)\s+(\S+),\s+(\S+),\s+(\S*)
person user7343922    schedule 25.09.2017
comment
Ну, это это ответ, но он требует некоторого объяснения. Ответы, содержащие только код, имеют очень ограниченную ценность. - person Gert Arnold; 26.09.2017