繁体   English   中英

查找和替换文件中的单词/行

[英]Find and replace words/lines in a file

我有一个文件(更具体地说,是一个 log4j 配置文件),我希望能够读入该文件并挑选出代码中的某些行并替换它们。 例如,在文件中有一个文本字符串,指示它存储的目录或记录器的级别。 我希望能够在不读取文件、将其写入另一个文件和删除原始文件的情况下替换这些文本字符串。 有没有更有效的方法来使用 Java 查找和替换文件中的文本?

这是我正在尝试使用的文本文件的示例:

log4j.rootLogger=DEBUG, A0

log4j.appender.A0=org.apache.log4j.RollingFileAppender
log4j.appender.A0.File=C:/log.txt
log4j.appender.A0.MaxFileSize=100KB
log4j.appender.A0.MaxBackupIndex=1

log4j.appender.A0.layout=org.apache.log4j.RollingFileAppender
log4j.appender.A0.layout.ConversionPattern=%-4r [%t] %-5p: %c %x - %m%n

我希望能够读取文件并将“DEBUG”替换为另一个级别或替换文件目录名称“C:/log.txt”。 日志配置文件也是用xml写的。 下面是一个例子。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender class="org.apache.log4j.RollingFileAppender" name="A0">
        <param name="append" value="false"/>
        <param name="File" value="C:/log/.txt"/>
        <param name="MaxBackupIndex" value="1"/>
        <param name="MaxFileSize" value="100KB"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-4r [%t] %-5p: %c %x - %m%n"/>
        </layout>
    </appender>
    <root>
        <level value="DEBUG"/>
        <appender-ref ref="A0"/>
    </root>
</log4j:configuration>

我在想可以对这种类型的实现使用哈希映射吗?

任何体面的文本编辑器都有支持正则表达式的搜索和替换功能。

但是,如果您有理由在 Java 中重新发明轮子,则可以执行以下操作:

Path path = Paths.get("test.txt");
Charset charset = StandardCharsets.UTF_8;

String content = new String(Files.readAllBytes(path), charset);
content = content.replaceAll("foo", "bar");
Files.write(path, content.getBytes(charset));

这仅适用于 Java 7 或更新版本。 如果您坚持使用较旧的 Java,则可以执行以下操作:

String content = IOUtils.toString(new FileInputStream(myfile), myencoding);
content = content.replaceAll(myPattern, myReplacement);
IOUtils.write(content, new FileOutputStream(myfile), myencoding);

在这种情况下,您需要添加错误处理并在完成后关闭流。

IOUtils记录在http://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html

在访问了这个问题并注意到所选解决方案的最初关注点之后,我想我会为那些不使用 Java 7 的人贡献这个,Java 7 使用 FileUtils 而不是 Apache Commons 的 IOUtils。 这里的优点是readFileToStringwriteStringToFile会自动为您处理关闭文件的问题。 (writeStringToFile 没有记录它,但您可以阅读源代码)。 希望这个食谱可以为任何新遇到这个问题的人简化事情。

  try {
     String content = FileUtils.readFileToString(new File("InputFile"), "UTF-8");
     content = content.replaceAll("toReplace", "replacementString");
     File tempFile = new File("OutputFile");
     FileUtils.writeStringToFile(tempFile, content, "UTF-8");
  } catch (IOException e) {
     //Simple exception handling, replace with what's necessary for your use case!
     throw new RuntimeException("Generating file failed", e);
  }
public static void replaceFileString(String old, String new) throws IOException {
    String fileName = Settings.getValue("fileDirectory");
    FileInputStream fis = new FileInputStream(fileName);
    String content = IOUtils.toString(fis, Charset.defaultCharset());
    content = content.replaceAll(old, new);
    FileOutputStream fos = new FileOutputStream(fileName);
    IOUtils.write(content, new FileOutputStream(fileName), Charset.defaultCharset());
    fis.close();
    fos.close();
}

以上是我对适用于我的 Meriton 示例的实现。 文件名是目录(即 D:\\utilities\\settings.txt)。 我不确定应该使用什么字符集,但我刚才在 Windows XP 机器上运行了这段代码,它在不进行临时文件创建和重命名的情况下完成了这个技巧。

您可能希望使用 Scanner 来解析并找到要修改的特定部分。 也有 Split 和 StringTokenizer 可能有用,但在您在 Scanner 工作的级别上可能是需要的。

以下是有关它们之间区别的一些附加信息: Scanner vs. StringTokenizer vs. String.Split

这是我通常使用脚本语言的那种事情。 能够使用 Ruby/Perl/Python 之类的工具非常简单地执行这些类型的转换非常有用(在此处插入您最喜欢的脚本语言)。

我通常不会为此使用 Java,因为它在开发周期/打字等方面太重量级了。

请注意,如果您想特别处理 XML,建议将文件作为 XML 读取并按原样操作(上述脚本语言具有非常有用且简单的 API 来完成此类工作)。 简单的文本搜索/替换可能会使您的文件在字符编码等方面无效。与往常一样,这取决于您的搜索/替换要求的复杂性。

您可以使用 Java 的Scanner类来解析文件的单词并在您的应用程序中处理它们,然后使用BufferedWriterFileWriter写回文件,应用更改。

我认为有一种更有效的方法可以在某个时候获取扫描仪的迭代器位置,以便更好地实现编辑。 但是由于文件可以打开以供读取或写入,因此我不确定。

在任何情况下,您都可以使用已经可用的库来解析 XML 文件,这些库已经实现了所有这些,并且可以让您轻松地做您想做的事。

暂无
暂无

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

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