У меня от 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
Использование 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 ""}}'