简体   繁体   中英

Method to pull specific lines from an external text file?

I am given a text file containing hundreds of line of information, and am tasked with pulling lines with a specific strings out. The issue is that after the line with the string being searched for is found, I also need to pull the 7 lines above it as-well.

I know this solution works for pulling specific line number. However I don't know what line number needs to be pulled, just the string on the line, along with 7 lines above the line, with the string I need.

file = File.open "file.txt"

n.times{ file.gets }
p $_

file.close

Let target? be a method that takes a line from the file as an argument and returns true or false , depending upon whether the lines meets the matching criterion.

Code

def doit(fname)
  arr = []
  File.foreach(fname).with_object([]) do |line, a|
    arr.shift if arr.size == 8
    arr << line    
    if target?(line) && arr.size == 8
      a << arr
      arr = []        
    end
  end
end

Example

Let's create a test file.

TARGET_LINES = ["Mary had a little lamb", "whose fleece was", "white as snow"]
a = (1..28).map { |i| "line #{i}" } 
b = [*a[0,7],  TARGET_LINES[1],
     *a[8,10], TARGET_LINES[2],
     *a[18,9], TARGET_LINES[0],
     a[27]]
FName = 'test'
File.write(FName, b.join("\n"))
  #=> 261 

See what we have (skipping some lines).

puts File.read(FName)
line 1
line 2
...
line 7
whose fleece was
line 9
line 10
...
line 18
white as snow
line 19
line 20
...
line 27
Mary had a little lamb
line 28

Now create a target? method:

def target?(line)
  TARGET_LINES.include?(line.chomp)
end

and execute doit :

puts doit(FName)
line 1
line 2
...
line 7
whose fleece was
line 12
line 13
...
line 18
white as snow
line 21
line 22
...
line 27
Mary had a little lamb

See the docs IO::foreach and Enumerator#with_object and Array#rotate . Note that IO class methods such as foreach are often invoked with the receiver File . This is permitted because File is a subclass of IO . ( File < IO #=> true ).

I know this is supposed to be a Ruby question, but sometimes other tools make it easier to get the results.

Did you know about grep ? :

$ cat long_file.txt
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
target
line 11
line 12
line 13
line 14

$ grep -B 7 target long_file.txt
line 4
line 5
line 6
line 7
line 8
line 9
line 10
target

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM