简体   繁体   English

如何grep在文件中查找模式并在其后存储内容?

[英]How to grep for a pattern in a file and store the content following it?

My file content is 我的文件内容是

blablabla    
Name  : 'XYZ'  
Age   : '30'  
Place : 'ABCD'    
blablabla  

How can I grep for "Name", "Age", "Place" and store name "XYZ", age "30" and place "ABCD" in a hash? 我该如何为“名称”,“年龄”,“地点”和商店名称“ XYZ”,年龄“ 30”以及“ ABCD”放置在哈希表中?

What should be the '?' 什么是“?” in this code to get those? 在这段代码中得到那些?

data = {}
name = /Name/
age = /Age/
place = /Place/
read_lines(file) { |l|
  case l
    when name
      data[:name] = ?
    when age
      data[:age] = ?
    when place
      data[:place]= ?
  end
}

You can use something like this. 您可以使用类似这样的东西。

data = {}
keys = {:name => "Name", :age => "Age", :place => "Place"}

File.open("test.txt", "r") do |f|
  f.each_line do |line|
    line.chomp!
    keys.each do |hash_key, string|
      if line[/#{string}/]
        data[hash_key] = line.strip.split(" : ")[-1].gsub("'", "")
        break
      end
    end
  end
end

output 输出

p data
# => {:name=>"XYZ", :age=>"30", :place=>"ABCD"}

Strange code, but in this case: 奇怪的代码,但在这种情况下:

  data[:name] = l.split(':')[1] if l.match(name)
when age
  data[:age] = l.split(':')[1] if l.match(age)
when place
  data[:place]= l.split(':')[1] if l.match(place)

Are you interested in refactoring? 您对重构感兴趣吗?

One option is to: 一种选择是:

mapping =
    [
        { name: :name, pattern: /Name/ },
        { name: :age, pattern: /Age/ },
        { name: :place, pattern: /Place/ }
    ]
data = str.split(/\r?\n|\r/).map do |line|
  mapping.map{|pair|
    { pair[:name] => line.split(' : ')[1].gsub("'", "") } if line.match(pair[:pattern])
  }.compact.reduce({}, :merge)
end.reduce({}, :merge)

Suppose we first read the file into a string: 假设我们首先将文件读取为字符串:

str = File.read('fname')

which is: 这是:

str =<<_
blablabla
Name : 'XYZ'
Age : '30'
Place : 'ABCD'
blablabla
_
  #=> "blablabla\nName : 'XYZ'\nAge : '30'\nPlace : 'ABCD'\nblablabla\n"

Then use the regex 然后使用正则表达式

r = /
    ^                    # match beginning of line 
    Name\s*:\s*'(.*)'\n  # match 'Name`, ':' possibly surrounded by spaces, any number
                         # of any character in capture group 1, end of line
    Age\s*:\s*'(.*)'\n   # match 'Age`, ':' possibly surrounded by spaces, any number
                         # of any character in capture group 2, end of line
    Place\s*:\s*'(.*)'\n # match 'Place`, ':' possibly surrounded by spaces, any number
                         # of any character in capture group 3, end of line
    /x                   # free-spacing regex definition mode

with String#scan to form the hash: String#scan形成哈希:

[:name, :age, :place].zip(str.scan(r).first).to_h
  #=> {:name=>"XYZ", :age=>"30", :place=>"ABCD"} 

I'd do something like this: 我会做这样的事情:

str = <<EOT
blablabla    
Name  : 'XYZ'  
Age   : '30'  
Place : 'ABCD'    
blablabla  
EOT

str.scan(/(Name|Age|Place)\s+:\s'([^']+)/).to_h  # => {"Name"=>"XYZ", "Age"=>"30", "Place"=>"ABCD"}

scan will create sub-arrays if it sees pattern groups in the regular expression. 如果在正则表达式中看到模式组,则scan将创建子数组。 Those make it easy to turn the returned array of arrays into a hash. 这些使将返回的数组数组转换为哈希值变得容易。

If you need to fold the keys to lower-case, or convert them to symbols: 如果需要将键折叠为小写或将其转换为符号:

str.scan(/(Name|Age|Place)\s+:\s'([^']+)/)
  .map{ |k, v| [k.downcase, v] } # => [["name", "XYZ"], ["age", "30"], ["place", "ABCD"]]
  .to_h  # => {"name"=>"XYZ", "age"=>"30", "place"=>"ABCD"}

Or: 要么:

str.scan(/(Name|Age|Place)\s+:\s'([^']+)/)
  .map{ |k, v| [k.downcase.to_sym, v] } # => [[:name, "XYZ"], [:age, "30"], [:place, "ABCD"]]
  .to_h  # => {:name=>"XYZ", :age=>"30", :place=>"ABCD"}

Or some variation on: 或一些变化:

str.scan(/(Name|Age|Place)\s+:\s'([^']+)/)
   .each_with_object({}){ |(k,v), h| h[k.downcase.to_sym] = v}
# => {:name=>"XYZ", :age=>"30", :place=>"ABCD"}

If the example string truly is the complete file, and there won't be any other reoccurrence of the key/value pairs, then this will work. 如果示例字符串确实是完整的文件,并且键/值对不会再出现任何其他情况,那么它将起作用。 If there could be more than one then the resulting hash will not be correct because the subsequent pairs will stomp on the first one. 如果可能不止一个,那么生成的哈希将是不正确的,因为随后的配对将在第一个配对上脚。 If the file is as you said, then it'll work fine. 如果文件如您所说,则可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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