Как нарезать и складывать CSV-файл по количеству столбцов?

У меня есть файл CSV с ~ 2000 столбцами в строке, и мне нужно разрезать его на 6 столбцов. После нарезки ломтики следует сложить в кучу.

Например:

A1,B1,C1,D1,E1,F1,A2,B2,C2,D2,E2,F2
G1,H1,I1,J1,K1,L1,G2,H2,I2,J2,K2,L2

станет:

A1,B1,C1,D1,E1,F1
G1,H1,I1,J1,K1,L1
A2,B2,C2,D2,E2,F2
G2,H2,I2,J2,K2,L2

Как я могу сделать это из командной строки оболочки?

-1
04.07.2017, 13:30
4 ответа

Я сомневаюсь, что вы можете сделать это эффективно в одном процессе, поэтому я предлагаю сделать цикл, подобный

for (( i=1 ; i < 2000; i+=6 )); do
  j=$((i+5))
  cut -d, -f $i-$j your.csv
done
0
28.01.2020, 05:12

Pythonрешение:

образец входного файлаtest.csv:

A1,B1,C1,D1,E1,F1,A2,B2,C2,D2,E2,F2,A3,B3,C3,D3,E3,F3,A4,B4,C4,D4,E4,F4
G1,H1,I1,J1,K1,L1,G2,H2,I2,J2,K2,L2,G3,H3,I3,J3,K3,L3,G4,H4,I4,J4,K4,L4

фрагмент _на _6.pyскрипт:

import sys, csv
with open(sys.argv[1], 'r') as fh:  # opening csv file
    reader = list(csv.reader(fh))   # reader object which will iterate over lines in the given csvfile
    cnt = len(reader[0])//6         # number(count) of slices
    for i in range(cnt):
        for l in reader:
            print(','.join(l[i*6:6*(i+1)]))  # outputting each slice from each line consecutively

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

python slice_on_6.py test.csv

Выход:

A1,B1,C1,D1,E1,F1
G1,H1,I1,J1,K1,L1
A2,B2,C2,D2,E2,F2
G2,H2,I2,J2,K2,L2
A3,B3,C3,D3,E3,F3
G3,H3,I3,J3,K3,L3
A4,B4,C4,D4,E4,F4
G4,H4,I4,J4,K4,L4
0
28.01.2020, 05:12

Всегда есть почтенныйrs:

rs -c, -T < file.csv | split -l6 --filter='rs -C, -T'
A1,B1,C1,D1,E1,F1,
G1,H1,I1,J1,K1,L1,
A2,B2,C2,D2,E2,F2,
G2,H2,I2,J2,K2,L2,

Чтобы удалить конечные разделители, вы можете передать черезsed 's/,$//'

rs -c, -T < file.csv | split -l6 --filter='rs -C, -T' | sed 's/,$//'
A1,B1,C1,D1,E1,F1
G1,H1,I1,J1,K1,L1
A2,B2,C2,D2,E2,F2
G2,H2,I2,J2,K2,L2

FWIW Я не знаю, почему rsдобавляет завершающий разделитель; у него есть опция

-m      Do not trim excess delimiters from the ends of the output array.

, что предполагает, что по умолчанию должно удалить его.

0
28.01.2020, 05:12

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

Затем мы распределяем первые 6 элементов, затем распечатываем эту часть и перемещаем эту линию в конец пространства шаблона (после отпиливания напечатанной части ).

Промойте и повторите описанный выше процесс для теперь ведущей линии в пространстве шаблона.

Этот процесс останавливается, когда в пространстве шаблона остается только последняя часть последней строки, и в этот момент мы просто позволим sedраспечатать ее после удаление ведущей новой строки.

Части представляют собой 6 полей csv, а общее количество полей в каждой строке равно целое число, кратное 6, и каждая строка имеет одинаковое количество полей.

sed -e '
   $!{
      s/$/,/
      N;s/^/\n/;D
   }

   s/^\([^,]*,\n\{0,1\}\)\{6\}/&\n/
   s/\n\n/\n/
   s/,\n/\n/

   P

   y/\n_/_\n/
   s/^[^_]*_//
   s/^\([^_]*\)_\(.*\)/_\2_\1/
   y/\n_/_\n/

   /\n.*\n/D
   s/.*\n//
' yourfile.csv

Результаты

A1,B1,C1,D1,E1,F1
G1,H1,I1,J1,K1,L1
A2,B2,C2,D2,E2,F2
G2,H2,I2,J2,K2,L2
0
28.01.2020, 05:12

Теги

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