我有一个文件,其内容如下所示:
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
我想:
- 查找以关键字 2009 开头的所有行。
- 将这些行添加到所有后续行的前面,直到找到另一个以 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
复制保持缓冲区并将其附加到刚刚读入模式空间的行。现在图案空间中有两行,我们需要在打印之前交换顺序并组合它们。带反向引用的替换模式就是这样做的。