簡體   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