Как впоследствии добавить заголовок к выводу команды awk?

Как впоследствии добавить заголовок к выводу команды awk?

Я создаю файл (выход) из другого файла (вход) с помощью 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редактирование происходит на месте, и мне не нужно ждать, пока весь файл будет скопирован, или хранить его в памяти.

Связанный контент