我有一个文本文件,其中包含多个类似于以下示例的条目:
public Completable getUserInfo() {
return storeProvider.getToken()
.flatMap(token -> webProvider.getUserInfo(token))
.flatMapCompletable(userInfo -> storeProvider.saveUserInfo(userInfo));
}
我需要想出一种方法,最好是在Bash或Perl中,用# 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
读取行,该行的子集基于第8列(纬度),如果满足条件,则打印其余部分行(例如LM ...),直到到达#
的下一行为止。例如,我只想打印第8 <-34.4列的“条目”,并包括该条目的LM *行。
我可以拿出代码来读取每条#
行,但是我不确定如何编程“如果满足条件,请打印LM行,直到到达下一条#行”。预期的输出将是:
#
答案 0 :(得分:5)
如果标志打开,则以#
开头的行会打印,否则设置标志(并打印)要符合条件
perl -wlnE'
if (/^\s*[^#]/) { say if $y } elsif ((split)[7] < -34.4) { $y=1, say }
' file
使用file
中提供的示例输入,将打印预期的输出。
标志-lnE
可以改为-ne
,在代码中用print
代替say
。 -w
仅用于警告,通常在单行代码中会省略(我经常使用它)。参见Command switches in perlrun
答案 1 :(得分:3)
perl -lane '$matches = ($F[7] < -34.4); print if ($matches .. (/^#/ and not $matches)) and ($matches or not /^#/)'
有点涉及。您可以将$matches
设为所需的# ...
行上的任何表达式。 ($matches .. (/^#/ and not $matches))
匹配所有标题行,直到并包括下一个(可能不匹配的)标题,然后and ($matches or not /^#/)
排除所有不匹配的标题。
(..
是Range Operator,是专门为这些用例设计的)
答案 2 :(得分:2)
使用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
没有一行的原因。
答案 3 :(得分:1)
另一种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
$