考虑以下数据(假设位于 file.txt 中):
P 5 24 0 0 -9.0786328019999996e+02 9.1141809916739828e+02 8.0419002445999993e+01 22 0 0 -6 0
P 8 24 -3.9196518724924090e+00 2.0727804903086735e+00 -8.9632605571651516e+02 8.9993737237679568e+02 8.0419002445999993e+01 44 0 0 -65 0
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
E 2 -1 -1.0000000000000000e+00 XXX
P 5 24 0 0 -6.7702324192000003e+02 6.8178272642703166e+02 8.0419002445999993e+01 22 0 0 -6 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0
E 3 -1 -1.0000000000000000e+00 -1.0000000000000000e+00 YY
即一般来说它具有以下形式
P ..
...
P ..
E ..
P ..
...
P ..
E ..
您能否告诉我是否可以制作一个仅包含P ..
之前行的文件E ..
?
即文件与
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0
答案1
使用grep
(因为你用它标记了grep),并假设我们使用的工具实现具有非标准选项,-B
用于提取匹配行以及一些前面的行:
$ grep -B 1 '^E' file.txt | grep '^P'
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0
这使用了grep
两次,首先提取所有以 开头的行E
以及这些行之前的任何行,然后提取以P
该行开头的行。
效果是您将得到以 开头的那些行,P
后面紧接着是以 开头的行E
。
将第二个的输出重定向grep
到文件以将其保存在某个文件中。
使用,记住变量中awk
以 开头的任何行,并在看到以 开头的行时打印(并清除)它:P
pline
E
$ awk '/^P/ { pline = $0 } /^E/ && length(pline) > 0 { print pline; pline = "" }' file
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0
使用sed
并假设行仅单独出现,而不是在两个或多个连续行的组中出现(如果出现,您将获得每行输出一次的E
最新行):P
E
$ sed -e '/^P/ { h; d; }' -e 'g' file
P 88 24 -4.2389618700766505e+00 1.2238515466784179e+00 -8.9698474520778257e+02 9.0059331315537133e+02 8.0419002445999993e+01 62 0 0 -89 0
P 8 24 -5.6932512713246979e+01 4.6556691594912991e+01 -6.3984521745934762e+02 6.4905928450035572e+02 8.0419002445999993e+01 44 0 0 -9 0
这会将任何P
行保存到保留空间并立即开始下一个循环。如果该行不是一行,则从保留空间中取出P
最近保存的行并输出。P
(基于相同的假设,awk
上面的代码可以缩短为awk '/^P/ { pline = $0; next } { print pline }' file
将代码直译sed
为awk
)