Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find and replace words in a text file using Java

Tags:

java

I am trying to find and replace certain words in a text file using Java. My code works to an extent however the output that I am getting is wrong. I need to replace multiple words from a line in a text file with user input. However, when I run my code the line copies itself once for every word I am trying to replace.

For example if I want to replace 3 words from the following:

python ycsb phase db -s -P /home/james/YCSB/workloads/workloada -p 
db.url=db://IP:port -p db.database=name

I end up with 3 copies of the line, each with a different word replaced. Rather than 1 line with all 3 of the required words replaced. Code provided below, thanks in advance.

public static void main(String[] args) {

    System.out.print("Phase: ");
    Scanner sp = new Scanner(System.in);
    String p = sp.nextLine();
    
    System.out.print("Database: ");
    Scanner sd = new Scanner(System.in);
    String d = sd.nextLine();
    
    System.out.print("IP address: ");
    Scanner sip = new Scanner(System.in);
    int ip = sip.nextInt();
     
    try {
        File file = new File("C://users//James//Desktop//newcommand.txt");
        BufferedReader reader = new BufferedReader(new FileReader(file));
        String line = "", oldtext = "";
        while((line = reader.readLine()) != null) {
            oldtext += line + "\r\n";
        }
        reader.close();
       
        String phase  = oldtext.replaceAll("phase", "" + p);
        String database = oldtext.replaceAll("db", "" + d);
        String ips = oldtext.replaceAll("IP", "" + ip);
        
        FileWriter writer = new FileWriter("C://users//James//Desktop//newcommand.txt");
        writer.write(phase + ips + database);
        writer.close();
    } catch (IOException e) {
        // handle e
    }
}
like image 218
JamesF Avatar asked Mar 15 '15 01:03

JamesF


2 Answers

if I understand well the situation, maybe the problem is that you are replacing the same string,and storing in different var,

try that:

  public static void main(String[] args) {
        System.out.print("Phase: ");
        Scanner sp = new Scanner(System.in);
        String p;
        p = sp.nextLine();

        System.out.print("Database: ");
        Scanner sd = new Scanner(System.in);
        String d;
        d = sd.nextLine();

        System.out.print("IP address: ");
        Scanner sip = new Scanner(System.in);
        int ip = sip.nextInt();

        {
         try
             {
             File file = new File("C://users//James//Desktop//newcommand.txt");
             BufferedReader reader = new BufferedReader(new FileReader(file));
             String line = "", oldtext = "";
             while((line = reader.readLine()) != null)
                 {
                 oldtext += line + "\r\n";
             }
             reader.close();

             String replacedtext  = oldtext.replaceAll("phase", "" + p);
             replacedtext = replacedtext.replaceAll("db", "" + d);
             replacedtext = replacedtext.replaceAll("IP", "" + ip);

             FileWriter writer = new FileWriter("C://users//James//Desktop//newcommand.txt");
             writer.write(replacedtext);


             writer.close();

         }
         catch (IOException ioe)
             {
             ioe.printStackTrace();
         }
     }
like image 187
Ricardo Umpierrez Avatar answered Sep 19 '22 07:09

Ricardo Umpierrez


Better version of existing answers:

public static void main(String[] args)
{
    Scanner sp = new Scanner(System.in);
    System.out.print("Phase: ");
    String pstr = s.nextLine();
    System.out.print("Database: ");
    String dstr = s.nextLine();
    System.out.print("IP address: ");
    String ipstr = String.valueOf(s.nextInt());

After reading the input we can use two efficient methods to read from the file, and write back. First I suggest writing to a temporary file (this is how sed replaces text in a file too). An advantage of this method is that the final move is probably going to be an atomic operation.

    File f = new File("C://users//James//Desktop//newcommand.txt");
    File ftmp = new File("C://users//James//Desktop//~tmp.newcommand.txt", ".txt");
    try
    {
        BufferedReader br = new BufferedReader(new FileReader(f));
        BufferedWriter bw = new BufferedWriter(new FileWriter(ftmp));
        String ln;
        while((ln = br.readLine()) != null)
        {
            bw.write(ln
                .replace("phase", pstr)
                .replace("db", dstr)
                .replace("IP", ipstr)
            );
            bw.newLine();
        }
        br.close();
        bw.close();
        Files.move(ftmp.toPath(), f.toPath(), StandardCopyOption.REPLACE_EXISTING);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }

Or if you really don't want to have a temporary file, and thus keep everything in RAM, then use this code:

    File f = new File("C://users//James//Desktop//newcommand.txt");
    try
    {
        String ENDL = System.getProperty("line.separator");

        StringBuilder sb = new StringBuilder();

        BufferedReader br = new BufferedReader(new FileReader(f));
        String ln;
        while((ln = br.readLine()) != null)
        {
            sb.append(ln
                .replace("phase", pstr)
                .replace("db", dstr)
                .replace("IP", ipstr)
            ).append(ENDL);
        }
        br.close();

        BufferedWriter bw = new BufferedWriter(new FileWriter(f));
        bw.write(sb.toString());
        bw.close();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }

Don't forget the closing bracket ;)

}

Note that - in contrary to the other answers - I am using .replace instead of .replaceAll. The only difference is that the latter interprets the first argument as a regular expression instead of a literal string. Both replace all occurrences, in this case there's no need for regular expressions and might only result in unwanted behavior due to special characters.

like image 43
Yeti Avatar answered Sep 21 '22 07:09

Yeti