Добавлять счетчик для нескольких одинаковых слов столбцов только в первой строке файла с Java - PullRequest
0 голосов
/ 13 января 2019

Я хочу получить доступ только к первой строке огромного текстового файла (.txt / .csv), чтобы изменить повторяющиеся слова, добавив счетчик и записав его обратно.

Другими словами: в заголовке texfile есть несколько одинаковых имен столбцов, которые необходимо изменить перед импортом в другую систему.

Пример ввода:
Col1, Col2, WWAB., WWAB., WWAB., WWAB., WWCD., WWCD., WWCD., Столбец99

В качестве примера текстовый файл с именем mytest.txt выглядит следующим образом:
Col1, Col2, WWAB., WWAB., WWAB., WWAB., WWCD., WWCD., WWCD., Столбец99
1,2,3,4,5,6,7,8,9,10
А, В, С, D, Е, F, G, H, I, J

Мой пример кода:

import java.io.IOException;
import java.io.RandomAccessFile;

public class ChangeTextFileHeader {

public static void main(String[] args) throws IOException {
RandomAccessFile raFile = null;

raFile = new RandomAccessFile("C:/mytest.txt", "rw"); // define File with read/write permission
int i;
String strOut;
raFile.seek(0); // sets pointer to the start of text
String csvHeader = raFile.readLine(); // read the first line (Header)
System.out.println("Header: " + csvHeader); // show original Header

for (i = 1; i <= 5; i = i + 1) {
    raFile.seek(0); // start pointer
    //replace textparts with counter
    strOut = csvHeader;
    strOut = strOut.replaceFirst("WWAB.", "WWAB" + i).replaceFirst("WWCD.", "WWCD" + i);
    System.out.println("Loop "+i+": " + strOut); // show original Header
    raFile.writeBytes(strOut); // write changes and continue from start
    }

raFile.seek(0);
System.out.println("Result: " + raFile.readLine()); //show result of written Header
raFile.close(); //close File

} }

Пример вывода должен быть:
Col1, Col2, WWAB1, WWAB2, WWAB3, WWAB4, WWCD1, WWCD2, WWCD3, Столбец99

К сожалению, он производит:
Col1, Col2, WWAB5, WWAB., WWAB., WWAB., WWCD5, WWCD., WWCD., Столбец99

Пожалуйста, покажите мне ваш рабочий код. Спасибо.

Ответы [ 2 ]

0 голосов
/ 15 января 2019
//this is how i quickly fixed my original code with the help of this community
import java.io.IOException;
import java.io.RandomAccessFile;

public class ChangeTextFileHeader {

public static void main(String[] args) throws IOException {

RandomAccessFile raFile = null;
int i;

raFile = new RandomAccessFile("c:/mytest.txt", "rw"); // define file with read/write permission
raFile.seek(0); // set start pointer of filestream
String csvHeader = raFile.readLine(); // read the first line (=header)
System.out.println("Header: " + csvHeader); // show original header

csvHeader = csvHeader.replaceAll("\\.","@"); //replace all dots in header (a dot means "any character")
raFile.seek(0); // (re)set start pointer of filestream

for (i = 1; i <= 5; i = i + 1) {
csvHeader = csvHeader.replaceFirst("WWAB@", "WWAB" + i).replaceFirst("WWCD@", "WWCD" + i); //replace textparts with counter
System.out.println("Loop " + i + ": " + csvHeader); // show current header
raFile.writeBytes(csvHeader); // write changes of replace
raFile.seek(0); // goto start of filestream again to search next replace in the loop
}

System.out.println("Result: " + csvHeader); // show result of modified header
raFile.close(); //close filestream

 }
}
0 голосов
/ 13 января 2019

Ваша проблема в том, что replaceFirst() принимает в качестве 1-го параметра регулярное выражение
и когда вы делаете

replaceFirst("WWAB.", "WWAB" + i)

точка . означает любой символ !
После 1-го матча, когда WWAB. заменяется на WWAB1
WWAB1 снова сопоставляется и заменяется на WWAB2 и так далее.
Поэтому одним из решений является замена каждого . другим символом перед началом замены, например:

strOut = strOut.replace(".", "@");

, затем найдите и замените WWAB@.
Я не воспроизводил ваш код, так как мне легче найти следующее решение:

public static void main(String[] args) {
    File file = new File("C:/mytest.txt");
    List<String> lines;
    try {
        lines = new ArrayList<>(Files.readAllLines(file.toPath(), StandardCharsets.UTF_8));
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }

    if (lines.size() == 0)
        return;

    String firstLine = lines.get(0).trim();
    if (firstLine.isEmpty())
        return;

    char c = '@';
    firstLine = firstLine.replace('.', c);
    String[] toReplace = {"WWAB", "WWCD"};

    for (String s : toReplace) {
        int j = 0;
        while (firstLine.contains(s + c)) {
            j++;
            firstLine = firstLine.replaceFirst(s + c, s + j);
        }
    }

    lines.set(0, firstLine);

    try {
        Files.write(file.toPath(), lines, StandardCharsets.UTF_8);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
...