Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
342 views
in Technique[技术] by (71.8m points)

perl start and end line number of match

I have the following perl command: perl -l -0777 -sne 'print $& if /Q$start_wordEs*({(?:[^{}]++|(?1))*+})/s' -- -start_word="${start_head}" < $path

It extracts some text from a file, but I'm also interestind between which two lines the text is extracted. Before it prints out the text I want it to print something like: The text is located between lines 3 and 7.

Sample input (start_head="START"):

Hello World
START{
   here are
    {some lines}
}
more text
down here

Expected Output:

The text is located between lines 2 and 5.
START{
   here are
    {some lines}
}

Current output after calling the perl command doesn't include The text is located between lines 2 and 5.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can try something like this:

perl -l -0777 -sne 'if (/Q$start_wordEs*({(?:[^{}]++|(?1))*+})/s) {($start, $end, $match) = ($-[0], $+[0], $&); print "The text is located between lines ", scalar(() = substr($_, 0, $start) =~ /(
*
|
)/g) + 1 , " and ", scalar( () = substr($_, 0, $end) =~ /(
*
|
)/g) + 1; print $match;}' -- -start_word="${start_head}" < $path

I made it slightly more verbose for clarity.

Test input (Linux end of lines ( )):

1. Hello World
2. Hello World
3. Hello World
4. Hello World
START{
   here are
    {some lines}
}
more text
down here

Output:

The text is located between lines 5 and 8
START{
   here are
    {some lines}
}

The same input with Dos/Windows line terminators ( ) do produce the same output.

If you are sure your input text file lines types will be either Mac ( ) or Linux/Unix ( ) but never Dos/Windows ( ) then it can be simplified like this:

perl -l -0777 -sne 'if (/Q$start_wordEs*({(?:[^{}]++|(?1))*+})/s) {print "The text is located between lines ", substr($_, 0, $-[0]) =~ tr/[
]// + 1 , " and ", substr($_, 0, $+[0]) =~ tr/[
]+// + 1; print $&;}' -- -start_word="${start_head}" < $path

Output (with the same input):

The text is located between lines 5 and 8
START{
   here are
    {some lines}
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...