English 中文(简体)
• 如何在两种相同的标识模式之间选择界线,这种模式可能发生多种情况,使用w/per或任何其他指挥线工具
原标题:How to select lines between two same marker patterns which may occur multiple times with awk/perl or any other command line tool

使用<代码>wk或perl 或任何指挥线工具,我如何选择在两个标识模式之间发生的界线? 这些模式可能有多个章节。 因此,这些障碍首先发生,在模式的第二次出现时结束。 在此之后,所有事情都被忽视,直至出现一种被视为首次出现和重复的模式。

例如: 证明文件载有:

abc
def1
ghi1
jkl1
abc
1
2
3
abc
def2
ghi2
jkl2
abc
4
5
6
abc
stu
abc

模式是荒谬的。 因此,我需要产出如下:

abc
def1
ghi1
jkl1
abc
abc
def2
ghi2
jkl2
abc
abc
stu
abc

我从其他相关问题尝试了各种解决办法,但都是不同的开端和终点模式。

如何在两种模式之间印刷线,一种是包容性的,另一种是排他性的(斜体为AWK或Perl)。

文档中两种类型之间的线外线

Extract text between 2 markers Extract lines between 2 tokens in a text file using bash

我根据我的需要更新了解决办法,其中审视了这样的情况:

perl -lne  if(/abc/){$flag=1; print} elsif(/abc/){$flag=0}  file.txt
awk  /abc/,/abc/  file.txt

我最后只是看上去了含有模式的界线,而不是两者的案文。

我如何在<代码>awk或perl上这样做。 或者任何指挥线工具,例如,我拿着同样模式的文字堵塞?

最佳回答

range营运人,三功能变量

perl -wne /abc/ ... /abc/ and print  data.txt

Another way, with an explicit flag and all but more concise

perl -wnlE  /abc/ and $f ^= 1; $f and say  data.txt

This doesn t print the end marker though. To have both start and end markers printed

perl -wnlE  ($f or /abc/) and say; /abc/ and $f ^= 1  data.txt

解释——

In Perl all logical营运人. Short-range。 审议<代码>A和B:如果第一种表述(A)对“falsey”进行评价,则<代码>B即为未评价<>/em>——该代码不适用。 因此,<代码>A和B主要相当于if (A){B }

I use the short-circuiting nature here to streamline code for a one-liner; it s normally far clearer in normal code to write it out nicely. So, the first statement amounts to

  • if ($f or /abc/) { say } -- print the line if $f evaluates to "truthy" (flag is set) or we are on the line with abc. The second condition is matched by regex, $_ =~ m/abc/, where m may be omitted with // delimiters and the pattern binds to $_ by default so that can be omitted as well -- for /abc/, which returns true/false.

    Now for setting that flag...

  • 接下来的发言,我们测试了/abc/,如果-it-matches-then (short-rangeing and),我们做的是$f ^= 1。 第二种表述使用如下的双目<代码>^。

    When two numbers are bitwise XOR-ed each pair of their bits is XOR-ed -- the resulting bit is set if one of them is set but not the other, and it s not set otherwise. So 0101 ^ 1100 gives 1001 (higher four bits omitted here; needed for testing)

    Then doing it with 1 results in flipping the lowest bit: 6 ^ 1 produces 7 (0110 ^ 1 --> 0111) while 7 ^ 1 returns 6. And we flip between 0 and 1. Then we assign that back, $f = $f ^ 1; for which there is syntax $f ^= 1.

    因此,如果该国旗为未定(0--->1,则以与abc的行文为准,则按下行的需要设定。


当然,从文档和线末线上读到的斜线,可以使用<条码><>>><>/条码>,而不是<条码>:<>条码/代码>,然后只需要<条码>-wne转换。

I just liked say better here. Also, -lE with say handles a case where this filter is fed strings wihtout linefeeds, as well.

问题回答

I would harness GNU AWK for this task following way, let file.txt content

be
abc
def1
ghi1
jkl1
abc
1
2
3
abc
def2
ghi2
jkl2
abc
4
5
6
abc
stu
abc

之后

awk  $0=="abc"{cnt+=1;print;next}cnt%2  file.txt

gives output

abc
def1
ghi1
jkl1
abc
abc
def2
ghi2
jkl2
abc
abc
stu
abc

Explanation: If whole line ($0) is abc 之后 increase cnt by one, output it and go forth to next line. For all others lines output it if and only if cnt is odd (remainder of division by 2 is non-zero). Disclaimer: this solution assumes that marker always spans whole line, if this does not hold true ignore this answer entirely.

(在GNUwk 5.1.0中测试)

使用任何 a子:

$ awk  /^abc$/{ if (++c%2) { rec="" } else { print rec $0; next } } {rec=rec $0 ORS}  file
abc
def1
ghi1
jkl1
abc
abc
def2
ghi2
jkl2
abc
abc
stu
abc

你们需要在2个限制者之间保存记录,否则,如果在最后的“abc”号之后有奇数的“abc”号,即使按要求在2个“abc”之间,例如考虑到这一投入:

$ cat file1
abc
good
abc
abc
bad

这只印刷了“abc”一对口的文字:

$ awk  /^abc$/{ if (++c%2) { rec="" } else { print rec $0; next } } {rec=rec $0 ORS}  file1
abc
good
abc

但用这一投入尝试任何其他现有答案:

$ perl -wnlE  ($f or /abc/) and say; /abc/ and $f ^= 1  file1
abc
good
abc
abc
bad

$ awk  $0=="abc"{cnt+=1;print;next}cnt%2  file1
abc
good
abc
abc
bad

$ awk  /abc/&&!((f=!f)&&f);f  file1
abc
good
abc
abc
bad

如果在<条码>abc之间出现其他情形,例如<条码>fooabcbar>/code>,则我期望你在其中某些方面遇到问题。

$ awk  $0="abc"&&(!(f=!f))&&!f;f  file

这与:

$ awk  
$0="abc" {
    if(!(f=!f))
        print
}
{
    if(f)
        print
}  file

产出:

abc
def1
ghi1
jkl1
abc
abc
def2
ghi2
jkl2
abc
abc
stu
abc

Using De Morgan s Law, 可以简化为:

$ awk  $0="abc" &&!((f=!f)&&f);f  file

If your data has Windows line-endings ( ) you need to set -v RS=" " (or RS=" ? ").

$ awk  
    FNR==NR && /abc/{i++; next} 
    FNR==1{last=int(i/2)*2} 
    /abc/ && j<last{ j++; f=!f; print; next } 
    f
  file file




相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签