Как отредактировать заголовок огромного CSV-файла на месте?

У меня есть несколько огромных файлов CSV, в которых я хочу поменять имена двух столбцов.

Я не хочу изменять / копировать / переписывать данные.

Операция очень дешевая в C: fopen файл, fgets заголовок, fseek или же rewindманипулировать заголовком (сохраняя его длину), fputs новый заголовок, fclose файл.

Это также можно сделать в ANSI Common Lisp ( CLISP, SBCL или GCL):

 (with-open-file (csv "foo.csv" :direction :io
                      :if-exists :overwrite)
   (let ((header (read-line csv)))
     (print header)
     (file-position csv 0)
     (write-line (string-upcase header) csv)
     (file-position csv 0)
     (read-line csv)))

и занимает доли секунды (sed занимает несколько минут, потому что он читает и перезаписывает весь файл, даже если вы говорите ему изменить только первую строку, игнорируя важную информацию о том, что размер заголовка не изменился).

Как это сделать с помощью "стандартных инструментов Unix" (например, perl)?

4 ответа

Решение

Если вы не знаете длину заголовка, head -n1 кажется разумным способом получить первую строчку.

Чтобы записать его обратно в начало файла, вы можете использовать dd:

head -n1 file.csv | ./do-some-processing | dd of=file.csv bs=1 conv=notrunc

conv=notrunc очень важно оставить оставшуюся часть файла без изменений, и bs=1 это остановиться на границе байта.

Я бы предложил sed для этого вы можете указать, чтобы сделать замену только в первой строке, например 1s/foo/bar/:

$ cat file
col1,col2,col3
1,2,3
3,2,1
...

$ sed -e '1s/col1/tmp/' -e '1s/col3/col1/'  -e '1s/tmp/col3/' file
col3,col2,col1
1,2,3
3,2,1
...

использование -i сохранить изменения обратно в файл:

$ sed -i -e '1s/col1/tmp/' -e '1s/col3/col1/'  -e '1s/tmp/col3/' file

Если все, что вам нужно, это поменять местами два слова, то все, что вам нужно, это перезапись нескольких байтов на месте.

Это простая задача для шестнадцатеричного редактора командной строки.

Я бы посоветовал hexedit который я только что использовал для редактирования 30 Гб .csv файл. Время, потраченное на открытие / сохранение файла, было незначительным (менее секунды). На самом деле мое время было потрачено на поиск сочетаний клавиш... (TAB переключиться на отображение ASCII, Ctrl-X сохранить и выйти).

Или, может быть, "заголовок" файла, чтобы удалить первую строку в отдельный файл.

Затем измените заголовочный файл и объедините их вместе.

Другие вопросы по тегам