我在一个文件中有数百万条记录,看起来像这样
echo "NEW Cell"
grep "2553,24" out.2A25.20090308.64436.7.HDF.txt.text = 22.58 5.39 82.09 237
echo "NEW Cell"
grep "2555,20" out.2A25.20090308.64436.7.HDF.txt.text = 24.72 5.58 82.05 237
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75 5.62 82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34 5.58 82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2 5.57 82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69 5.62 82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74 5.60 82.30 120
echo "NEW Cell"
grep "2560,24" out.2A25.20090308.64436.7.HDF.txt.text = 19.38 5.54 82.30 170
echo "NEW Cell"
现在我想删除带有“grep”的行,条件是它是包含“New Cell”的行之间的唯一行。也就是说,如果新单元格之间有一行 grep,则应删除该行。
这个怎么做?
我的输出应该是这样的,
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75 5.62 82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34 5.58 82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2 5.57 82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69 5.62 82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74 5.60 82.30 120
AWK
解决方案:/NEW Cell/{ f=1; n=NR+2; r=$0; next }
- 在遇到线与NEW Cell
f=1
= 设置活动标志f=1
n=NR+2
- 设置n
为以下要处理的最大行数(下 2 行)r=$0
- 捕获线next
- 跳到下一条记录f && n-NR==1 && /^grep /
- 遇到以关键字n-NR==1
开头的第二行(由 确保)grep
gr=$0; next
- 捕获grep
线并跳转到下一个(第三个)记录NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }
- 在遇到第三条关键线时(由 保证NR==n
)if (/NEW Cell/) { f=0 }
- 如果已处理部分下的第 3 行包含NEW Cell
- 重置当前处理f=0
(跳过所有先前捕获的行)else print r ORS gr
- 否则打印所有以前捕获的行输出:
紧凑型解决方案
sed
:如果该行不包含
NEW Cell
执行H
将该行附加到保留空间并d
停止对该行的处理。所以进一步的命令只适用于
NEW Cell
行:x
交换模式空间和保持空间,因此该行现在在保持空间中并且可以附加更多的行,而模式空间包含附加到最后NEW Cell
一行的所有内容。您的要求是行之间有不止一行NEW Cell
,因此模式空间中必须至少有两个换行符。如果没有,请删除它而不输出:/\n.*\n/!d
.用基本
awk
...版本 1 只会删除
grep
遵循 OP 描述的行:版本 2 将删除单独
grep
的行以及遵循 OP 示例输出的前面的非 grep 行:版本 2 的可读形式...
可以通过将内容放入文件(例如
awkfile
)和awk -f awkfile inputfile
.解释:
RS='echo "NEW Cell"\n'
-RS
是输入记录分隔符,默认为换行符。现在它被更改为echo "NEW Cell"\n
,因此,该字符串的所有出现都将被删除,并且它们之间的所有字符都成为记录项。/\n.+\n/{
- 仅适用于与此模式匹配的记录 - 换行符、一个或多个字符、换行符。所以,它只匹配多行记录,单行记录不匹配,因为它只有一个\n
.printf("%s%s", RS, $0);
- 打印以RS
(echo "NEW Cell"\n
) 开头的记录。输出