У меня есть сценарий, где строки должны быть добавлены в начале и в конце огромных файлов.
Я попытался, как показано ниже.
для первой строки:
sed -i '1i\'"$FirstLine" $Filename
для последней строки:
sed -i '$ a\'"$Lastline" $Filename
Но проблема этой команды в том, что она добавляет первую строку файла и пересекает весь файл. Для последней строки он снова пересекает весь файл и добавляет последнюю строку. Так как его очень большой файл (14 ГБ) занимает очень много времени.
Как добавить строку в начало, а другую в конец файла, читая файл только один раз?
источник
for
цикл:for file in Tes*; do [command]; done
"$file"
,Tes*
а не в качестве аргументаed
.Обратите внимание, что если вы хотите избежать размещения всей копии файла на диске, вы можете сделать следующее:
При этом используется тот факт, что когда его стандартный ввод / вывод является файлом,
sed
чтение и запись выполняется по блокам. Итак, здесь можно переопределить файл, который он читает, до тех пор, пока первая строка, которую вы добавляете, меньшеsed
размера блока (это должно быть что-то вроде 4k или 8k).Обратите внимание, что если по какой-то причине
sed
произойдет сбой (убит, сбой машины ...), вы получите половину обработанного файла, что будет означать, что некоторые данные размером с первую строку отсутствуют где-то посередине.Также обратите внимание, что если вы
sed
не используете GNUsed
, это не будет работать для двоичных данных (но поскольку вы используете-i
, вы используете GNU sed).источник
Вот несколько вариантов (каждый из которых создаст новую копию файла, поэтому убедитесь, что у вас достаточно места для этого):
простое эхо / кошка
awk / gawk и т. д.
awk
и тому подобное читать файлы построчно.BEGIN{}
Блок выполняется до первой строки иEND{}
блока после последней строки. Итак, команда выше означаетprint "first" at the beginning, then print every line in the file and print "last" at the end
.Perl
По сути, это то же самое, что вышеописанный gawk, написанный на Perl.
источник
sed -i
который создает временные файлы.Я предпочитаю гораздо проще:
Это преобразует файл:
в файл:
источник
Вы можете использовать Vim в режиме Ex:
1
выберите первую строкуi
вставить текст и перевод строки$
выберите последнюю строкуa
добавить текст и перевод строкиx
сохранить и закрытьисточник
Невозможно вставить данные в начало файла¹, все, что вы можете сделать, это создать новый файл, записать дополнительные данные и добавить старые данные. Таким образом, вам придется переписать весь файл хотя бы один раз, чтобы вставить первую строку. Однако вы можете добавить последнюю строку, не переписывая файл.
Кроме того, вы можете объединить две команды в одном запуске sed.
sed -i
создает новый выходной файл, а затем перемещает его поверх старого файла. Это означает, что во время работы sed существует вторая копия файла, занимающая место. Вы можете избежать этого, перезаписав файл на месте , но с серьезными ограничениями: добавляемая строка должна быть меньше буфера sed, и в случае сбоя системы вы получите поврежденный файл и некоторое содержимое, потерянное в средний, поэтому я настоятельно рекомендую против этого.¹ В Linux есть способ вставки данных в файл, но он может вставлять только целое число блоков файловой системы, он не может вставлять строки произвольной длины. Это полезно для некоторых приложений, таких как базы данных и виртуальные машины, но бесполезно для текстовых файлов.
источник
fallocate()
сFALLOC_FL_INSERT_RANGE
доступны на XFS и ext4 в современных ядрах (4.xx) man7.org/linux/man-pages/man2/fallocate.2.htmlисточник
Современные ядра Linux (выше 4.1 или 4.2) поддерживают вставку данных в начало файла с помощью
fallocate()
системного вызова сFALLOC_FL_INSERT_RANGE
файловыми системами ext4 и xfs. По сути, это логическая операция смещения: данные логически перемещаются с большим смещением.Существует ограничение в отношении степени детализации диапазона, который вы хотите вставить в начало файла. Но для текстовых файлов вы, вероятно, можете выделить немного больше, чем требуется (до границы гранулярности) и заполнить пробелами или возвратом каретки, но это зависит от вашего приложения
Я не знаю ни одной доступной утилиты linux, которая манипулирует экстентами файлов, но написать ее несложно: получить дескриптор файла и вызвать
fallocate()
с соответствующими аргументами. Для получения дополнительной информации см. Справочную страницуfallocate
системного вызова: http://man7.org/linux/man-pages/man2/fallocate.2.html.источник
fallocate
утилиту. Проблема в том, что гранулярность целых блоков делает это бесполезным для большинства текстовых файлов. Другая проблема заключается в том, что распределение диапазона и последующее изменение не являются атомарными. Так что это на самом деле не решает проблему здесь.fallocate
атомарность нарушена, пожалуйста, мне любопытно)