Добавить разделители для подразумеваемых пустых полей - PullRequest
0 голосов
/ 21 февраля 2020

Я ищу простое решение, чтобы в каждой строке было одинаковое количество запятых в файле (CSV-файл)

например

пример файла:

1,1
A,B,C,D,E,F
2,2,
3,3,3,
4,4,4,4

ожидается:

1,1,,,,
A,B,C,D,E,F
2,2,,,,
3,3,3,,,
4,4,4,4,,

строка с наибольшим количеством запятых имеет 5 запятых в этом случае (строка № 2). Итак, я хочу добавить другие запятые во всех строках, чтобы иметь одинаковый номер для каждой строки (т.е. 5 запятых)

Ответы [ 3 ]

2 голосов
/ 21 февраля 2020

Не могли бы вы попробовать следующий, более общий c способ. Этот код будет работать даже в том случае, если количество полей в файле Input_file не совпадает, и сначала он прочитает и получит максимальное количество полей из всего файла, а затем во 2-й раз при чтении файла сбросит поля (почему, поскольку мы установили OFS как, поэтому если текущий количество полей в строке меньше значения nf, эти запятые будут добавлены к этой строке). Улучшенная версия ответа @oguz ismail.

awk '
BEGIN{
 FS=OFS=","
}
FNR==NR{
 nf=nf>NF?nf:NF
 next
}
{
 $nf=$nf
}
1
'  Input_file  Input_file

Объяснение: Добавление подробного объяснения для кода выше.

awk '                ##Starting awk program frmo here.
BEGIN{               ##Starting BEGIN section of awk program from here.
 FS=OFS=","          ##Setting FS and OFS as comma for all lines here.
}
FNR==NR{             ##Checking condition FNR==NR which will be TRUE when first time Input_file is being read.
 nf=nf>NF?nf:NF      ##Creating variable nf whose value is getting set as per condition, if nf is greater than NF then set it as NF else keep it as it is,
 next                ##next will skip all further statements from here.
}
{
 $nf=$nf             ##Mentioning $nf=$nf will reset current lines value and will add comma(s) at last of line if NF is lesser than nf.
}
1                    ##1 will print edited/non-edited lines here.
' Input_file Input_file      ##Mentioning Input_file names here.
2 голосов
/ 21 февраля 2020

Еще один способ сделать так, чтобы все строки в CSV-файле имели одинаковое количество полей. Количество полей не должно быть известно. Поля max будут вычислены, и к каждой записи будет добавлена ​​подстрока необходимых запятых, например,

awk -F, -v max=0 '{
    lines[n++] = $0             # store lines indexed by line number
    fields[lines[n-1]] = NF     # store number of field indexed by $0
    if (NF > max)               # find max NF value
        max = NF
}
END {
    for(i=0;i<max;i++)          # form string with max commas
        commastr=commastr","
    for(i=0;i<n;i++)            # loop appended substring of commas 
        printf "%s%s\n", lines[i], substr(commastr,1,max-fields[lines[i]])
}' file

Пример использования / Вывод

Вставка по команде линия, вы получите:

$ awk -F, -v max=0 '{
>     lines[n++] = $0             # store lines indexed by line number
>     fields[lines[n-1]] = NF     # store number of field indexed by $0
>     if (NF > max)               # find max NF value
>         max = NF
> }
> END {
>     for(i=0;i<max;i++)          # form string with max commas
>         commastr=commastr","
>     for(i=0;i<n;i++)            # loop appended substring of commas
>         printf "%s%s\n", lines[i], substr(commastr,1,max-fields[lines[i]])
> }' file
1,1,,,,
A,B,C,D,E,F
2,2,,,,
3,3,3,,,
4,4,4,4,,
2 голосов
/ 21 февраля 2020

Использование awk:

$ awk 'BEGIN{FS=OFS=","} {$6=$6} 1' file
1,1,,,,
A,B,C,D,E,F
2,2,,,,
3,3,3,,,
4,4,4,4,,

Как вы можете видеть выше, в этом подходе макс. количество полей должно быть жестко задано в команде.

...