проблема с разбором CSV-файла, разделенного запятыми - PullRequest
1 голос
/ 18 марта 2010

Я пытаюсь извлечь 4-й столбец из CSV-файла (через запятую и пропускаю первые 2 строки заголовка) с помощью этой команды,

 awk 'NR <2 {next}{FS =","}{print $4}' filename.csv | more

Однако это не работает, потому что первый столбец содержит запятую, поэтому 4-й столбец на самом деле не 4-й. Ниже приведен пример строки:

"sdfsdfsd, sfsdf", 454, fgdfg, I_want_this_column, sdfgdg, 34546, 456465 и т. Д.

Ответы [ 5 ]

3 голосов
/ 18 марта 2010

Если у вас нет особых причин для использования awk, я бы порекомендовал использовать библиотеку разбора CSV. Многие языки сценариев имеют один встроенный (или, по крайней мере, доступный), и они избавят вас от этих головных болей.

1 голос
/ 18 марта 2010

, если в вашем первом столбце всегда есть кавычки,

 $ awk 'BEGIN{ FS="\042[ ]*," } { m=split($2,a,","); print a[3] } ' file
 I_want_this_column

если столбец, который вы хотите, всегда является последним вторым,

$ awk -F"," '{print $(NF-1)}' file
 I_want_this_column

Вы можете попробовать этот демонстрационный скрипт, чтобы разбить столбцы

awk 'BEGIN{ FS="," }
{
   for(i=1;i<=NF;i++){
      # save normal
      if($i !~ /^[ ]*\042|[ ]*\042[ ]*$/){
        a[++j]=$i
      }
      # if quotes at the end
      if(f==1 && $i ~ /[ ]*\042[ ]*$/){
        s=s","$i
        a[++j]=s
        #reset
        s="";f=0
      }
      # if quotes in front
      if($i ~ /^[ ]*\042/){
        s=s $i
        f=1
      }
      if(f==1 && ( $i !~/\042/ ) ){
         s=s","$i
      }
   }
}
END{
  # print columns
  for(p=1;p<=j;p++){
     print "Field "p,": "a[p]
  }
} ' file

выход

$ cat file
"sdfsdfsd, sfsdf", "454,fgdfg blah , words ", I_want_this_column,sdfgdg

$ ./shell.sh
Field 1 : "sdfsdfsd, sfsdf"
Field 2 : fgdfg blah
Field 3 :  "454,fgdfg blah , words "
Field 4 :  I_want_this_column
Field 5 : sdfgdg
0 голосов
/ 05 мая 2013

Работа со файлами CSV, в которых поля в кавычках заключены в запятые, может быть затруднена с помощью стандартных текстовых инструментов UNIX.

Я написал программу под названием csvquote, чтобы облегчить обработку данных. В вашем случае вы можете использовать это так:

csvquote filename.csv | awk 'NR <2 {next}{FS =","}{print $4}' | csvquote -u | more

или вы можете использовать обрезку и хвост, как это:

csvquote filename.csv | tail -n +3 | cut -d, -f4 | csvquote -u | more

Код и документы здесь: https://github.com/dbro/csvquote

0 голосов
/ 19 марта 2010

Если вы не можете избежать awk, этот фрагмент кода выполняет нужную вам работу:

BEGIN {FS=",";}

{
        f=0;
        j=0;
        for (i = 1; i <=NF ; ++i) {
                if (f) {
                        a[j] = a[j] "," $(i);
                        if ($(i) ~ "\"$") {
                                f = 0;
                        }
                }
                else {
                        ++j;
                        a[j] = $(i);
                        if ((a[j] ~ "^\"[^\"]*$")) {
                                f = 1;
                        }
                }
        }
        for (i = 1; i <= j; ++i) {
                gsub("^\"","",a[i]);
                gsub("\"$","",a[i]);
                gsub("\"\"","\"",a[i]);
print "i = \"" a[i] "\"";
        }
}
0 голосов
/ 18 марта 2010

Вы не должны использовать awk здесь. Используйте модуль Python csv или модули Perl Text :: CSV или Text :: CSV_XS или другой настоящий анализатор csv.

Схожий вопрос - парсинг CSV-файла с использованием gawk

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...