大日志文件截取,从指定日志文件中提取两个标记字符串之间的全部内容,Kotlin

大日志文件截取,从指定日志文件中提取两个标记字符串之间的全部内容,Kotlin

一个Kotlin编写的日志文件截取工具,用于从指定日志文件中提取两个标记字符串之间的内容。程序通过命令行交互获取文件路径、起始和结束标记字符串,验证输入后创建输出文件。使用UTF-8编码读取日志文件,当检测到起始标记时开始写入,遇到结束标记时停止。程序会处理文件名中的非法字符,并在操作完成后显示结果信息,包括复制行数和输出文件路径。如果未找到标记则会删除临时文件并提示错误。

Kotlin 复制代码
import java.io.File
import java.nio.charset.Charset

fun main() {
    println("请输入 log 文件路径 file path:")
    val filePath = readLine()?.trim()?.trim('"') ?: ""

    println("请输入起始匹配字符串 tag start:")
    val tagStart = readLine() ?: ""

    println("请输入结束匹配字符串 tag end:")
    val tagEnd = readLine() ?: ""

    if (filePath.isBlank()) {
        println("错误:filePath 不能为空")
        return
    }

    if (tagStart.isBlank()) {
        println("错误:tagStart 不能为空")
        return
    }

    if (tagEnd.isBlank()) {
        println("错误:tagEnd 不能为空")
        return
    }

    val sourceFile = File(filePath)

    if (!sourceFile.exists()) {
        println("错误:文件不存在:$filePath")
        return
    }

    if (!sourceFile.isFile) {
        println("错误:输入路径不是文件:$filePath")
        return
    }

    val safeTagStart = sanitizeFileName(tagStart)
    val safeTagEnd = sanitizeFileName(tagEnd)

    val outputFileName = "from_${safeTagStart}_to_${safeTagEnd}.txt"
    val outputFile = File(sourceFile.parentFile, outputFileName)

    var foundStart = false
    var foundEnd = false
    var copiedLineCount = 0

    /**
     * log 一般是 UTF-8。
     * 如果日志是 GBK,可以把 Charsets.UTF_8 改成 Charset.forName("GBK")
     */
    val charset: Charset = Charsets.UTF_8

    sourceFile.bufferedReader(charset).use { reader ->
        outputFile.bufferedWriter(charset).use { writer ->
            var line: String?

            while (true) {
                line = reader.readLine()
                if (line == null) {
                    break
                }

                val currentLine = line!!

                if (!foundStart) {
                    if (currentLine.contains(tagStart)) {
                        foundStart = true

                        writer.write(currentLine)
                        writer.newLine()
                        copiedLineCount++

                        if (currentLine.contains(tagEnd)) {
                            foundEnd = true
                            break
                        }
                    }
                } else {
                    writer.write(currentLine)
                    writer.newLine()
                    copiedLineCount++

                    if (currentLine.contains(tagEnd)) {
                        foundEnd = true
                        break
                    }
                }
            }
        }
    }

    if (!foundStart) {
        outputFile.delete()
        println("没有找到起始 tagStart:$tagStart")
        return
    }

    if (!foundEnd) {
        outputFile.delete()
        println("已经找到 tagStart,但在其后没有找到 tagEnd:$tagEnd")
        return
    }

    println("截取完成!")
    println("起始 tag start:$tagStart")
    println("结束 tag end:$tagEnd")
    println("复制日志行数:$copiedLineCount")
    println("输出文件路径:${outputFile.absolutePath}")
}

/**
 * Windows 文件名不能包含以下字符:
 * \ / : * ? " < > |
 *
 * 这里统一替换成下划线,避免生成文件失败。
 */
fun sanitizeFileName(name: String): String {
    val invalidChars = Regex("""[\\/:*?"<>|]""")
    return name
        .replace(invalidChars, "_")
        .replace(Regex("\\s+"), "_")
        .take(100)
}

运行

IntelliJ IDEA 安装 Kotlin 插件后,通常会自带 Kotlin compiler,路径一般类似:

复制代码
C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2024.3\plugins\Kotlin\kotlinc\bin

这个目录下通常会有:

复制代码
kotlinc.bat
kotlin.bat

临时配置 PATH

打开 Windows CMD,执行类似命令:

复制代码
set PATH=C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2024.3\plugins\Kotlin\kotlinc\bin;%PATH%

注意:要把路径改成你自己电脑上的真实路径。

然后验证:

复制代码
kotlinc -version

如果输出正确的kotlin版本号,表面配置成功。

执行编译:

Kotlin 复制代码
kotlinc AppMain.kt -include-runtime -d AppMain.jar

会生成一个AppMain.jar文件。

运行:

Kotlin 复制代码
java -jar AppMain.jar

推荐一个AI学习网站

相关推荐
Android打工仔12 小时前
Kotlin 协程源码解析(七)`delay()` 到底是如何在 `Dispatchers.Main` 上恢复的?
android·kotlin
Kapaseker17 小时前
适配小米“中”折屏,非得买一台吗
android·kotlin
菠萝加点糖17 小时前
Android applicationIdSuffix 详解
android·gitee·kotlin
事圆则缓1 天前
Kotlin 协程完全指南
开发语言·kotlin
蜡台1 天前
Kotlin 零基础完整版实战教程|从语法入门到Android工程实战
android·开发语言·kotlin
蜡台2 天前
Kotlin 五大作用域函数详解|let/run/apply/also/with 选型指南+实战避坑
android·java·kotlin
hai_android2 天前
Messenger:Android 最轻量的 IPC 方式
android·kotlin
hai_android2 天前
不用 AIDL,手把手教你手写 Binder 代理类
android·kotlin
雨白2 天前
Kotlin 泛型进阶:攻克型变与实化,直击痛点
kotlin
alexhilton3 天前
架构测试为何需要双视图
android·kotlin·android jetpack