Я создаю файл (вывод) из другого файла (ввод) с помощью awk (пропуская заголовок):
awk 'NR==1{next} $3==1 {print $1"\t"$2}' input > output
Затем у меня есть информация заголовка, которую я могу вычислить только потом, которую я добавляю с помощью sed:
sed -i "1s/^/head1\thead2\n/" output
Однако sed довольно медленный, мне интересно, есть ли лучший способ сделать это? Как сохранить результат awk и затем записать файл после того, как я получу информацию из заголовка?
Погуглив еще, я нашел этот вопрос: Изменить заголовок в огромном файле, не перезаписывая весь файл.
Чтобы избежать перезаписи всего файла при добавлении в заголовок, я напечатал фиктивный заголовок минимального количества байтов (дополняя нулями) при создании файла:
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
редактируется на месте, и мне не нужно ждать, пока будет скопирован весь файл, или хранить его в памяти.
Выглядит немного странно, но в моих тестах работает. Вы можете сделать тест.
echo -e "$head1\t$head2\n" "$(<file5)" >file5
Тест:
$ cat file5
home
help
$ echo -e "header1\theader2\n" "$(<file5)" >file5
$ cat file5
header1 header2
home
help
Попробуйте с bash :
echo -e "head1\thead2\n$(cat output)" > /tmp/out && mv /tmp/out output
Я бы сделал в bash
{ echo -e "head1\thead2" ; cat output ; } > newoutput
по сравнению с ответом Романа Перехреста, он будет работать правильно даже для очень длинных файлов (он сначала загрузит файл в память, а затем выполнит эхо; также bash имеет имхо некоторую максимальную длину ввода)
Если у вас есть тело в файле output
и нужный заголовок в файле с именем header
(printf "head1\thead2\n" > header
), то вы можете вставить заголовок с помощью:
ed -s output <<< $'0r header\nw\nq'
-s
говорит Подавить диагностический вывод (который будет означать, сколько байт он считывает из выход
, сколько байт он прочитал из заголовка
и сколько байтов он записал в конце).
Команды ed:
0r header
- в нулевой строке прочитать содержимое файла header
w
- записать файл q
- quit ed