Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用ruby删除文件的前两行_Ruby - Fatal编程技术网

用ruby删除文件的前两行

用ruby删除文件的前两行,ruby,Ruby,我的脚本读取大型文本文件,并用正则表达式抓取第一页。我需要删除每个第一页的前两行,或者将正则表达式更改为匹配==第1页==字符串后的1行。我在这里包括整个脚本,因为我在过去的问题中被要求这样做,而且我是ruby新手,并不总是知道如何将片段集成为答案: #!/usr/bin/env ruby -wKU require 'fileutils' source = File.open('list.txt') source.readlines.each do |line| line.strip!

我的脚本读取大型文本文件,并用正则表达式抓取第一页。我需要删除每个第一页的前两行,或者将正则表达式更改为匹配==第1页==字符串后的1行。我在这里包括整个脚本,因为我在过去的问题中被要求这样做,而且我是ruby新手,并不总是知道如何将片段集成为答案:

#!/usr/bin/env ruby -wKU
require 'fileutils'

source = File.open('list.txt')
source.readlines.each do |line|
  line.strip!
  if File.exists? line
    file = File.open(line)
  end

  text = (File.read(line))
  match = text.match(/==Page 1(.*)==Page 2==/m)
  puts match
end

现在,当你更新了你的问题时,我不得不删除一大部分这么好的答案:-)

我想你问题的关键在于你想使用
match[1]
而不是
match
。通过
Regexp.match
方法(
MatchData
)返回的对象可以像数组一样处理,它将整个匹配字符串作为第一个元素保存,并将每个子查询保存在以下元素中。因此,在您的例子中,变量
match
(和
match[0]
)是整个匹配字符串(连同“==Page..==”标记),但您只需要隐藏在
match[1]
中的第一个子表达式


现在谈谈我在代码中感觉到的其他小问题。如果你已经知道我说的话,请不要生气,但也许其他人会从这些警告中获益

代码的第一部分(
if File.exists?line
)正在检查文件是否存在,但代码只是打开了文件(没有关闭!),几行后仍在尝试打开文件

您可以改为使用此行:

next unless File.exists? line
第二件事是程序应该准备好处理文件没有页面标记的情况,因此它与模式不匹配。(然后变量
match
将为
nil

第三个建议是可以使用稍微复杂一点的模式。当前的(
/==Page 1==(.*)==Page 2==/m
)将返回以行尾标记作为第一个字符的页面内容。如果使用此模式:

/==Page 1==\s*\n(.*)==Page 2==/m
/==Page 1==\s*\n(.*\n)==Page 2==/m
然后子表达式将不包含与“==第1页==`文本放在同一行中的空格。如果您使用此模式:

/==Page 1==\s*\n(.*)==Page 2==/m
/==Page 1==\s*\n(.*\n)==Page 2==/m
然后您将确保“==Page 2==”标记从行的开头开始

第四个问题是程序员(当然有时包括我)往往忘记在打开文件后关闭它。在您的例子中,您已经打开了“source”文件,但是在代码中没有
source。在循环后关闭
语句。处理文件最安全的方法是将块传递给
File.open
方法,因此您可以使用程序第一行的以下形式:

File.open('list.txt') do |source|
  source.readlines.each do |line|
…但在这种情况下,只写以下内容会更干净:

File.readlines('list.txt').each do |line|
综上所述,代码可能如下所示(为了提高代码可读性,我将变量
line
更改为
fname
):

#/usr/bin/env ruby-wKU
需要“fileutils”
File.readlines('list.txt')。每个do | fname|
fname.strip!
下一步,除非File.exists?文件名
text=File.read(fname)
如果match=text.match(/==第1页==\s*\n(.*\n)==第2页==/m)
#整个“页面”(字符串):
放置匹配项[1]。检查
#没有前两行的“页面”:
#(如果您确实想删除行):
放置匹配项[1]。拆分(“\n”)[2..-1]。检查
其他的
#如果文件与模式不匹配,该怎么办?
raise“文件#{fname}不包括页分隔符。”
结束
结束

您能表达一下您希望代码做什么吗?对我来说是这样的:我想删除存储在另一个文件中的列表中包含的每个文件的前2行。对吗?对不起,编辑好了。你是对的,我想删除列表中每个文件的前两行。我已经更新了答案。我希望我已经发现了您的问题:-)(通过评论通知,因为我不知道询问者是否收到了关于答案更新的通知)