Проблемы с преобразованием файла фиксированной ширины в CSV - PullRequest
0 голосов
/ 26 ноября 2018

извините, если это вопрос новичка, но я не нашел ответа на этот конкретный вопрос по stackoverflow.У меня есть (очень большой) файл данных фиксированной ширины, который выглядит следующим образом: simplefile.txt

ratno      fdate ratname                        typecode country        
12346 31/12/2010 HARTZ                              4    UNITED STATES
12444 31/12/2010 CHRISTIE                           5    UNITED STATES
12527 31/12/2010 HILL AIR                           4    UNITED STATES
15000 31/12/2010 TOKUGAVA  INC.                     5    JAPAN
37700 31/12/2010 HARTLAND                           1    UNITED KINGDOM
37700 31/12/2010 WILDER                             1    UNITED STATES  
18935 31/12/2010 FLOWERS FINAL SERVICES INC         5    UNITED STATES
37700 31/12/2010 MAPLE CORPORATION                  1    CANADA
48614 31/12/2010 SERIAL MGMT  L.P.                  5    UNITED STATES
 1373 31/12/2010 AMORE MGMT GROUP N A               1    UNITED STATES

Я пытаюсь преобразовать его в CSV-файл с помощью терминала (файл слишком большой для Excel) это будет выглядеть следующим образом:

ratno,fdate,ratname,typecode,country        
12346,31/12/2010,HARTZ,4,UNITED STATES
12444,31/12/2010,CHRISTIE,5,UNITED STATES
12527,31/12/2010,HILL AIR,4,UNITED STATES
15000,31/12/2010,TOKUGAVA  INC.,5,JAPAN
37700,31/12/2010,HARTLAND,1,UNITED KINGDOM
37700,31/12/2010,WILDER,1,UNITED STATES 
18935,31/12/2010,FLOWERS FINAL SERVICES INC,5,UNITED STATES
37700,31/12/2010,MAPLE CORPORATION,1,CANADA
48614,31/12/2010,SERIAL MGMT  L.P.,5,UNITED STATES
 1373,31/12/2010,AMORE MGMT GROUP N A,1,UNITED STATES

Я немного покопался на этом сайте и нашел возможное решение, основанное на команде оболочки awk:

awk -v FIELDWIDTHS="5 11 31 9 16" -v OFS=',' '{$1=$1;print}'   "simpletestfile.txt"

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

ratno,fdate,ratname,typecode,country
12346,31/12/2010,HARTZ,4,UNITED,STATES
12444,31/12/2010,CHRISTIE,5,UNITED,STATES
12527,31/12/2010,HILL,AIR,4,UNITED,STATES
15000,31/12/2010,TOKUGAVA,INC.,5,JAPAN
37700,31/12/2010,HARTLAND,1,UNITED,KINGDOM
37700,31/12/2010,WILDER,1,UNITED,STATES
18935,31/12/2010,FLOWERS,FINAL,SERVICES,INC,5,UNITED,STATES
37700,31/12/2010,MAPLE,CORPORATION,1,CANADA
48614,31/12/2010,SERIAL,MGMT,L.P.,5,UNITED,STATES
1373,31/12/2010,AMORE,MGMT,GROUP,N,A,1,UNITED,STATES

Как можно избежать вставки запятых в пробелы за пределами разграниченной ширины поля?Спасибо!

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Ваша попытка была удачной, но для встроенной переменной FIELDWIDTHS требуется gawk (gnu awk).С gawk:

$ gawk -v FIELDWIDTHS="5 11 31 9 16" -v OFS=',' '{$1=$1;print}' file

ratno,      fdate, ratname                       , typecode, country
12346, 31/12/2010, HARTZ                         ,     4   , UNITED STATES
12444, 31/12/2010, CHRISTIE                      ,     5   , UNITED STATES
12527, 31/12/2010, HILL AIR                      ,     4   , UNITED STATES

Предполагая, что вам не нужны лишние пробелы, вы можете вместо этого сделать следующее:

$ gawk -v FIELDWIDTHS="5 11 31 9 16" -v OFS=',' '{for (i=1; i<=NF; ++i) gsub(/^ *| *$/, "", $i)}1' file
ratno,fdate,ratname,typecode,country
12346,31/12/2010,HARTZ,4,UNITED STATES
12444,31/12/2010,CHRISTIE,5,UNITED STATES
12527,31/12/2010,HILL AIR,4,UNITED STATES

Если у вас нет gnu awk, вы можете добиться того жеРезультаты с:

$ awk -v fieldwidths="5 11 31 9 16" '
BEGIN { OFS=","; split(fieldwidths, widths) }
{
    rec = $0
    $0 = ""
    start = 1;
    for (i=1; i<=length(widths); ++i) {
        $i = substr(rec, start, widths[i])
        gsub(/^ *| *$/, "", $i)
        start += widths[i]
    }
}1' file

ratno,fdate,ratname,typecode,country
12346,31/12/2010,HARTZ,4,UNITED STATES
12444,31/12/2010,CHRISTIE,5,UNITED STATES
12527,31/12/2010,HILL AIR,4,UNITED STATES
0 голосов
/ 26 ноября 2018

perl удобен здесь:

perl -nE '                                     # read this bottom to top
    say join ",", 
        map {s/^\s+|\s+$//g; $_}               # trim leading/trailing whitespace
        /^(.{5}) (.{10}) (.{30}) (.{8}) (.*)/  # extract the fields
' simplefile.txt 
ratno,fdate,ratname,typecode,country
12346,31/12/2010,HARTZ,4,UNITED STATES
12444,31/12/2010,CHRISTIE,5,UNITED STATES
12527,31/12/2010,HILL AIR,4,UNITED STATES
15000,31/12/2010,TOKUGAVA  INC.,5,JAPAN
37700,31/12/2010,HARTLAND,1,UNITED KINGDOM
37700,31/12/2010,WILDER,1,UNITED STATES
18935,31/12/2010,FLOWERS FINAL SERVICES INC,5,UNITED STATES
37700,31/12/2010,MAPLE CORPORATION,1,CANADA
48614,31/12/2010,SERIAL MGMT  L.P.,5,UNITED STATES
1373,31/12/2010,AMORE MGMT GROUP N A,1,UNITED STATES

Хотя, для правильного CSV, нам нужно быть немного осторожнее с полями, содержащими запятые или кавычки.Если бы я чувствовал себя менее уверенно относительно содержимого файла, я бы использовал этот блок map:

map {s/^\s+|\s+$//g; s/"/""/g; qq("$_")}

, который выводит

"ratno","fdate","ratname","typecode","country"
"12346","31/12/2010","HARTZ","4","UNITED STATES"
"12444","31/12/2010","CHRISTIE","5","UNITED STATES"
"12527","31/12/2010","HILL AIR","4","UNITED STATES"
"15000","31/12/2010","TOKUGAVA  INC.","5","JAPAN"
"37700","31/12/2010","HARTLAND","1","UNITED KINGDOM"
"37700","31/12/2010","WILDER","1","UNITED STATES"
"18935","31/12/2010","FLOWERS FINAL SERVICES INC","5","UNITED STATES"
"37700","31/12/2010","MAPLE CORPORATION","1","CANADA"
"48614","31/12/2010","SERIAL MGMT  L.P.","5","UNITED STATES"
"1373","31/12/2010","AMORE MGMT GROUP N A","1","UNITED STATES"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...