基于子集文件的一行和打印其他行,直到到达下一行



我有一个文本文件,其中包含多个条目,如下所示:

# 2018 11 21 17 47 37.708756 -34.390213 116.803673 2.6972 0.442474 3.324627 2.840390 0.885880 890
LM01 0.836408 1.00 P
LM01 1.035398 1.00 S
LM03 3.987074 1.00 S
# 2018 11 22 11 58 25.550581 -34.439400 116.750832 2.8513 0.288144 3.306790 2.576028 0.771026 891
LM01 1.664419 1.00 P
LM01 2.471786 1.00 S
LM03 3.536432 1.00 P
# 2018 11 22 14 38 7.190175 -34.447819 116.788727 3.1661 0.577347 2.063253 2.132511 0.608057 892
LM01 1.629825 1.00 P
LM02 3.059825 1.00 P
LM03 3.284825 1.00 P
LM01 2.378885 1.00 S

我需要想出一种方法,最好是 Bash 或 Perl,它读取带有#的行,根据第 8 列(纬度)对该行进行子集,如果满足条件,则打印其余行(例如 LM...),直到它到达下一行与#。 例如,我只想打印第 8 列<-34.4 的"条目",并包含该条目的 LM* 行。

我可以想出代码来读取每#行,但我不确定如何编程"如果满足条件,请打印 LM 行,直到到达下一个 # 行"。 预期输出为:

# 2018 11 22 11 58 25.550581 -34.439400 116.750832 2.8513 0.288144 3.306790 2.576028 0.771026 891
LM01 1.664419 1.00 P
LM01 2.471786 1.00 S
LM03 3.536432 1.00 P
# 2018 11 22 14 38 7.190175 -34.447819 116.788727 3.1661 0.577347 2.063253 2.132511 0.608057 892
LM01 1.629825 1.00 P
LM02 3.059825 1.00 P
LM03 3.284825 1.00 P
LM01 2.378885 1.00 S

在不以 #开头的行上,如果标志打开,则打印,否则设置标志(和打印)取决于条件

perl -wlnE'
    if (/^s*[^#]/) { say if $y } elsif ((split)[7] < -34.4) { $y=1, say }
' file

使用file提供的示例输入,这将打印预期的输出。

可以改为-ne标志-lnE,在代码中使用print而不是say-w仅用于警告,通常在单行中省略(我总是使用它)。 请参阅 perlrun

gawk记录分隔符,perl应该有类似的...

$ awk -v RS='(^|n)#' '$7<-34.4{printf "%s", rt $0} {rt=RT}' file
# 2018 11 22 11 58 25.550581 -34.439400 116.750832 2.8513 0.288144 3.306790 2.576028 0.771026 891
LM01 1.664419 1.00 P
LM01 2.471786 1.00 S
LM03 3.536432 1.00 P
# 2018 11 22 14 38 7.190175 -34.447819 116.788727 3.1661 0.577347 2.063253 2.132511 0.608057 892
LM01 1.629825 1.00 P
LM02 3.059825 1.00 P
LM03 3.284825 1.00 P
LM01 2.378885 1.00 S

请注意,您需要<,因为符号为负数。 由于我们使用#作为记录分隔符,因此字段号少了一个。

我们将记录分隔符定义为前导 # 或换行符之后。 通常 RS 在记录之间,但在这里它领先于记录。 这就是为什么我们捕获匹配的记录分隔符RT并分配给要在(下一个)记录中使用的变量。 RT还包括新生产线,这就是为什么printf没有新线的原因。

另一个Perl单行

代码
  perl -0777 -ne ' while( /(^#.+?)(?=^#|Z)/gsm ) { print $1 if (split(" ",$1))[7] < -34.4 } '

带输入

$ cat geeb.txt
# 2018 11 21 17 47 37.708756 -34.390213 116.803673 2.6972 0.442474 3.324627 2.840390 0.885880 890
LM01 0.836408 1.00 P
LM01 1.035398 1.00 S
LM03 3.987074 1.00 S
# 2018 11 22 11 58 25.550581 -34.439400 116.750832 2.8513 0.288144 3.306790 2.576028 0.771026 891
LM01 1.664419 1.00 P
LM01 2.471786 1.00 S
LM03 3.536432 1.00 P
# 2018 11 22 14 38 7.190175 -34.447819 116.788727 3.1661 0.577347 2.063253 2.132511 0.608057 892
LM01 1.629825 1.00 P
LM02 3.059825 1.00 P
LM03 3.284825 1.00 P
LM01 2.378885 1.00 S
$ perl -0777 -ne ' while( /(^#.+?)(?=^#|Z)/gsm ) { print $1 if (split(" ",$1))[7] < -34.4 } ' geeb.txt
# 2018 11 22 11 58 25.550581 -34.439400 116.750832 2.8513 0.288144 3.306790 2.576028 0.771026 891
LM01 1.664419 1.00 P
LM01 2.471786 1.00 S
LM03 3.536432 1.00 P
# 2018 11 22 14 38 7.190175 -34.447819 116.788727 3.1661 0.577347 2.063253 2.132511 0.608057 892
LM01 1.629825 1.00 P
LM02 3.059825 1.00 P
LM03 3.284825 1.00 P
LM01 2.378885 1.00 S
$

最新更新