Я создаю файл (выход) из другого файла (вход) с помощью awk (пропуская заголовок):
awk 'NR==1{next} $3==1 {print $1"\t"$2}' input > output
Затем у меня есть информация заголовка, которую я могу вычислить только позже, и которую я добавляю с помощью sed:
sed -i "1s/^/head1\thead2\n/" output
Однако sed довольно медленный, мне интересно, есть ли способ сделать это лучше? Например, сохранить результат awk и затем записать файл после того, как у меня есть информация заголовка?
решение1
Если у вас есть тело в output
файле и нужный заголовок в файле с именем header
( printf "head1\thead2\n" > header
), то вы можете вставить заголовок с помощью:
ed -s output <<< $'0r header\nw\nq'
В нем -s
говорится о необходимости подавить диагностический вывод (который будет содержать информацию о том, сколько байт было считано из output
, сколько байт было считано из header
, и сколько байт было записано в конце).
Команды ed:
0r header
- в нулевой строке прочитать содержимое файлаheader
w
- записать файлq
- бросил ed
решение2
Попробуйте сБаш:
echo -e "head1\thead2\n$(cat output)" > /tmp/out && mv /tmp/out output
решение3
Я бы сделал в bash
{ echo -e "head1\thead2" ; cat output ; } > newoutput
по сравнению с ответом RomanPerekhrest, он будет работать правильно даже для очень длинных файлов (он сначала загрузит файл в память, а затем выполнит echo; также, по моему скромному мнению, у bash есть некоторая максимальная длина входных данных)
решение4
После дальнейшего гугления я нашел такой вопрос: Изменить заголовок в огромном файле, не переписывая весь файл.
Чтобы избежать необходимости переписывать весь файл при добавлении заголовка, я вывел фиктивный заголовок с минимальным количеством байтов (дополнив его нулями) при создании файла:
awk 'NR==1{print "dummyhead100\tdummyhead20000"; next} $3==1 {print
$1"\t"$2}' input > output
Затем я создаю файл (или строковую переменную) с новым заголовком как header.tsv и заменяю фиктивный заголовок на месте (предварительно убедившись, что фиктивный и новый заголовки имеют одинаковое количество байтов), используя dd
:
dd conv=notrunc obs=1 if=header.tsv of=output
В этом случае output
редактирование происходит на месте, и мне не нужно ждать, пока весь файл будет скопирован, или хранить его в памяти.