我想编写一个 Scala 脚本来递归处理目录中的所有文件。对于每个文件,我想看看是否有任何情况在第 X 行和第 X - 2 行出现字符串。如果发生这种情况,我想停止处理该文件,并将该文件名添加到 map 文件名的出现次数。我今天才开始学习 Scala,我已经得到了文件递归代码,需要一些字符串搜索方面的帮助,这是我目前所拥有的:
import java.io.File
import scala.io.Source
val s1= "CmdNum = 506"
val s2 = "Data = [0000,]"
def processFile(f: File) {
val lines = scala.io.Source.fromFile(f).getLines.toArray
for (i = 0 to lines.length - 1) {
// want to do string searches here, see if line contains s1 and line two lines above also contains s1
//println(lines(i))
}
}
def recursiveListFiles(f: File): Array[File] = {
val these = f.listFiles
if (these != null) {
for (i = 0 to these.length - 1) {
if (these(i).isFile) {
processFile(these(i))
}
}
these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
}
else {
Array[File]()
}
}
println(recursiveListFiles(new File(args(0))))
最佳答案
你可以这样做:
def processFile(f: File) {
val src = Source.fromFile(f)
val hit = src.getLines().sliding(3).exists{
case List(l0, l1, l2) => l0.contains(s1) && l2.contains(s1)
case _ => false
}
src.close
// do something depending on hit like adding to a Map
}
首先您不需要转换为数组,您可以保留迭代器以仅读取找到匹配项所需的行。
您可以使用 sliding
使用 3 行的滑动窗口获取派生迭代器,您可以在 i
和 i+2< 行中查找字符串
。
exists
测试此滑动迭代器的元素是否满足谓词。为了方便起见,case
会将滑动窗口元素中的 3 行模式匹配到 3 个值中。 我必须使用 REPL 来找出滑动真正返回的类型。
最后别忘了关闭src。
如果需要出现次数:
val count = src.getLines().sliding(3).filter{
case List(l0, l1, l2) => l0.contains(s1) && l2.contains(s1)
case _ => false
}.size
您过滤出现的次数,然后获取大小...
针对短于 3 行的文件的匹配错误进行了编辑
关于string - 斯卡拉 : cleanest way to recursively parse files checking for multiple strings,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4629984/