通过在数据行前面添加标题行来重新排列文本文件

通过在数据行前面添加标题行来重新排列文本文件

我有一个文件,其内容如下所示:

2009 150  0  0  0     0000
75.316   0.0400390625  0.00007        0.00000 0.8980
76.216   0.0400390625  0.00007        1.00000 0.9046
77.217   0.0400390625  0.00009        2.00000 0.9113
78.341   0.0400390625  0.00010        3.00000 0.9183
2009 150  2  0  0     0000
75.316   0.0400390625  0.00007        0.00000 0.8980
76.216   0.0400390625  0.00007        1.00000 0.9046
77.217   0.0400390625  0.00009        2.00000 0.9113
78.341   0.0400390625  0.00010        3.00000 0.9183
79.616   0.0400390625  0.00013        4.00000 0.9255

我想:

  1. 查找以关键字 2009 开头的所有行。
  2. 将这些行添加到所有后续行的前面,直到找到另一个以 2009 开头的行,依此类推,直到 EOF。

本质上我正在寻找这样的输出:

2009 150  0  0  0     0000 75.316   0.0400390625  0.00007        0.00000 0.8980
2009 150  0  0  0     0000 76.216   0.0400390625  0.00007        1.00000 0.9046
2009 150  0  0  0     0000 77.217   0.0400390625  0.00009        2.00000 0.9113
2009 150  0  0  0     0000 78.341   0.0400390625  0.00010        3.00000 0.9183
2009 150  2  0  0     0000 75.316   0.0400390625  0.00007        0.00000 0.8980
2009 150  2  0  0     0000 76.216   0.0400390625  0.00007        1.00000 0.9046

…………

我在这个问题上摸索了很长一段时间,但无法想出解决方案。如有帮助,将不胜感激。我知道如何使用标志提取关键字之间的文本,但我不确定这是否是正确的方向。

答案1

您可以awk为此使用:

awk '/^2009/{a=$0;next}{print a" "$0} ' file.txt

这只会在 2009 年第一个匹配项之前的任何行前面添加一个空格,您可以设置一个默认字符串作为前缀,如下所示:

awk 'BEGIN{a="My default prepend string";}/^2009/{a=$0;next}{print a" "$0} ' file.txt

答案2

我会用 Perl 这样做:

perl -lne 'if(/^2009/){$n=$_; next} print "$n $_"' file

或者,更简洁地说

perl -lne '/^2009/ ? ($n=$_) : print "$n $_"' file

这个想法是保存当前行($_在 Perl 中),就好像$n它以 开头一样2009,如果不是,则打印当前行以及 的当前值$n

答案3

使用sed

sed -n '
  /^2009/ { h }
  /^2009/ !{ G; s/^\(.*\)\n\(.*\)$/\2 \1/p }
  ' in_file

按要求解释:

-n-sed除非我们告诉它,否则不会打印任何内容。

/^2009/ { h }- 当我们到达以 开头的行时2009,将其放入保留缓冲区中。

/^2009/ !{...}- 内的模式{...}将应用于不以 开头的每一行2009

G; s/^\(.*\)\n\(.*\)$/\2 \1/p-G复制保持缓冲区并将其附加到刚刚读入模式空间的行。现在图案空间中有两行,我们需要在打印之前交换顺序并组合它们。带反向引用的替换模式就是这样做的。

相关内容