我使用 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
- 在第 0 行,读取文件的内容header
w
- 写出文件q
- 退出编辑
答案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
是就地编辑的,我不必等待整个文件被复制,或者必须将其保留在内存中。