Мне нужно объединить несколько файлов .csv вместе с неравным количеством строк

У меня от 3 до 5 файлов .csv, и мне нужно иметь возможность объединить их вместе, сохраняя при этом все в соответствующих столбцах. Ниже приведен простой пример с файлами с различным количеством строк. файл1 файл2 файл3 файл4 файл5> конечный файл.

Файл 1

1 1  
1 1  
1 1

Файл 2

2 2 2     
2 2 2 

Файл 3

3  
3  
3  
3 

Файл 4

4  
4  

Файл 5

5  
5  
5  
5  
5  

Мне нужны результаты в файле .csv, чтобы объединить все файлы вместе и сохранить все в соответствующих столбцах . В моем примере 0 - это пустые ячейки / столбцы.

Final File

1 1 2 2 2 3 4 5       
1 1 2 2 2 3 4 5   
1 1 0 0 0 3 0 5    
0 0 0 0 0 3 0 5  
0 0 0 0 0 0 0 5

Все, что я пробовал сейчас, сдвинет все влево, если в этих ячейках / столбцах нет данных.

Окончательный файл

1 1 2 2 2 3 4 5  
1 1 2 2 2 3 4 5   
1 1 3 5  
3 5  
5       
0
29.03.2016, 18:56
1 ответ

Использование csvkitбез заголовка -Hи отключение логического вывода -I(, в противном случае значения 1интерпретируются какTRUE

csvjoin -H -I file*  

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

a,b,a2,b2,c,a2_2,a2_3,a2_4
1,1,2,2,2,3,4,5
1,1,2,2,2,3,4,5
1,1,,,,3,,5
,,,,,3,,5
,,,,,,,5

Как вы будете заменять отсутствующие значения и терять разделитель, это дело вкуса, но вы можете перебирать поля в awk, устанавливая разделитель на -F",", пропуская заголовки NR>1и добавляя 0преобразовать NULLполя

csvjoin -H -I file* | awk -F"," 'NR>1{for (i=1; i<=NF; i++) printf ("%s ", $i+0); print""}'

Что приведет вас туда, где вы хотите быть

1 1 2 2 2 3 4 5 
1 1 2 2 2 3 4 5 
1 1 0 0 0 3 0 5 
0 0 0 0 0 3 0 5 
0 0 0 0 0 0 0 5

В качестве альтернативы чистая awkверсия предполагает, что количество полей постоянно в каждом файле

awk '{for (i=1; i<=NF; i++) {mx[FNR][nf+i]=$i}}
  ENDFILE{nf+=NF; nor=(nor<FNR)?FNR:nor}
  END{for (i=1;i<=nor;i++) {for (j=1;j<=nf;j++) printf ("%s ", mx[i][j]+0); print ""}}' file*

который просто загружает значения из каждого файла в массивmx[][]

{for (i=1; i<=NF; i++) {mx[FNR][nf+i]=$i}}

в конце каждого файла переместите индекс столбца nfвправо на количество полей в файле NFи возьмите большее из текущего количества записей NRили размера последней матрицы nor

. ]
ENDFILE{nf+=NF; nor=(nor<FNR)?FNR:nor}

И в конце просто переберите размеры матрицы и преобразуйте NULLзначения

END{for (i=1;i<=nor;i++) {for (j=1;j<=nf;j++) printf ("$s ", mx[i][j]+0); print ""}}'
0
14.03.2020, 07:52

Теги

Похожие вопросы