Использование awk или perl для извлечения определенных столбцов из CSV (синтаксический анализ)

Фон - Я хочу извлечь определенные столбцы из файла csv. CSV-файл разделен запятыми, использует двойные кавычки в качестве квалификатора текста (необязательно, но если поле содержит специальные символы, квалификатор будет там - см. пример), и использует обратную косую черту в качестве escape-символа. Это также возможно для некоторых полей. быть пустым.


Пример ввода и желаемого вывода - Например, я хочу, чтобы в выходном файле были только столбцы 1, 3 и 4. Окончательный извлечение столбцов из файла csv должно соответствовать формату исходного файла. Не следует удалять управляющие символы или добавлять дополнительные кавычки и тому подобное.

Входные данные

"John \"Super\" Doe",25,"123 ABC Street",123-456-7890,"M",A
"Jane, Mary","",132 CBS Street,333-111-5332,"F",B
"Smith \"Jr.\", Jane",35,,555-876-1233,"F",
"Lee, Jack",22,123 Sesame St,"","M",D

Желаемый результат

"John \"Super\" Doe","123 ABC Street",123-456-7890
"Jane, Mary",132 CBS Street,333-111-5332
"Smith \"Jr.\", Jane",,555-876-1233
"Lee, Jack",123 Sesame St,""

Предварительный сценарий (awk) - Ниже приведен предварительный сценарий, который, как я обнаружил, работает для по большей части, но не работает в одном конкретном случае, который я заметил, и, возможно, в нескольких что я еще не видел и не думал

#!/usr/xpg4/bin/awk -f

BEGIN{  OFS = FS = ","  }

/"/{
    for(i=1;i<=NF;i++){
        if($i ~ /^"[^"]+$/){
            for(x=i+1;x<=NF;x++){
                $i=$i","$x
                if($i ~ /"+$/){
                    z = x - (i + 1) + 1
                    for(y=i+1;y<=NF;y++)
                        $y = $(y + z)
                    break
                }
            }
            NF = NF - z
            i=x
        }
    }
print $1,$3,$4
}

Вышеупомянутое, кажется, работает хорошо, пока не встретит поле, содержащее как экранированные двойные кавычки, так и запятую. В этом случае синтаксический анализ будет отключен и вывод будет некорректным.


Вопрос / Комментарии - Я читал, что awk - не лучший вариант для синтаксического анализа файлов csv, поэтому рекомендуется использовать perl. Однако я вообще не знаю Perl.Я нашел несколько примеров сценариев Perl, но они не дают желаемого результата, который я ищу, и я не знаю, как легко редактировать сценарии для того, что я хочу.

Что касается awk, я знаком с ним и время от времени использую его основные функции, но я не знаю многих дополнительных функций, таких как некоторые команды, используемые в приведенном выше сценарии. Возможен ли мой желаемый результат просто с помощью awk? Если да, можно ли отредактировать приведенный выше сценарий, чтобы решить проблему, с которой я столкнулся? Может ли кто-нибудь построчно объяснить, что именно делает сценарий?

Любая помощь будет принята с благодарностью, спасибо!

7
задан mob 15 February 2012 в 04:42
поделиться