Как отредактировать заголовок огромного 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
сохранить и выйти).
Или, может быть, "заголовок" файла, чтобы удалить первую строку в отдельный файл.
Затем измените заголовочный файл и объедините их вместе.