2016-11-10 2 views
0

У меня здесь действительно странный fileformat, который использует вкладки и пробелы в любой сумме для разделения полей (даже трейлинг-и ведущих). Другая специальность заключается в том, что поля могут быть добавлены с пробелами в них, которые затем экранируются CSV.Разделенные столбцы, разделенные вкладками и пробелами

Один пример:

0 "some string" 234  23947  123 ""some escaped"string"" 

Я пытаюсь разобрать такие столбцы с AWK и я должен был бы иметь каждый элемент в массиве, например,

foo[0] -> 0 
foo[1] -> "some string" 
foo[2] -> 234 
foo[3] -> 23947 
foo[4] -> 123 
foo[5] -> ""some escaped"string"" 

Возможно ли это? Я прочитал http://web.archive.org/web/20120531065332/http://backreference.org/2010/04/17/csv-parsing-with-awk/, в котором говорится, что синтаксический анализ csv уже очень тяжелый (для начала этого должно быть достаточно для разбора нормальных строк с пробелами, экранированный вариант очень редок)

Прежде чем я начну долгое время: сделать это в awk или лучше использовать какой-либо другой язык?

+0

ваше время будет лучше потратить уговаривая правильно форматированный вывод из системы производителя; -/(Да, CSV и инструменты unix имеют разные принципы, лежащие в их основе.) Удачи. – shellter

+0

@shellter haha: D это, вероятно, не произойдет ... файлы генерируются некоторым программным обеспечением, работающим только на окнах, с некоторой половиной письменной документации, и я пытаюсь преобразовать их в несколько читаемый формат ...:/Разработчик уже сказал, что не будет поддерживать какое-либо программное обеспечение рядом с ним, поэтому единственный способ - преобразовать файлы самостоятельно. Интересно, как он может читать файлы в своем продукте? – reox

+0

После быстрого взгляда я бы сказал, что решение должно быть сдержанным или если будет использоваться регулярное выражение, которое Awk не поддерживает. Я должен сказать, что его действительно сложно сделать с awk, и кто-то собирается его прописать за 15 минут ... –

ответ

1

С GNU AWK для FPAT:

$ cat tst.awk 
BEGIN { FPAT="\\S+|\"[^\"]+\"|,[^,]+," } 
{ 
    gsub(/@/,"@A") 
    gsub(/,/,"@B") 
    gsub(/""/,",") 
    for (i=1; i<=NF; i++) { 
     gsub(/,/,"\"\"",$i) 
     gsub(/@B/,",",$i) 
     gsub(/@A/,"@",$i) 
     print i, $i 
    } 
} 

$ awk -f tst.awk file 
1 0 
2 "some string" 
3 234 
4 23947 
5 123 
6 ""some escaped"string"" 

Чтобы понять, что это делает, см https://stackoverflow.com/a/40512703/1745001

+1

nice что кто-то разместил Q, который тестирует и доказывает вашу модель с довольно экстремальным случаем ;-) – shellter

Смежные вопросы