4

I'm trying to count the number of lines of a text file using a unix command from java code.

My code looks like:

String filePath = "/dir1/testFile.txt";

Runtime rt = Runtime.getRuntime();
Process p;
try {
    System.out.println("No: of lines : ");
    findLineCount = "cat " + filePath + " | wc -l";
    p = rt.exec(findLineCount);
    p.waitFor();
} catch (Exception e) {
    //code
}

But, nothing is displayed in the console. When I execute the command directly, it works. What could be the issue in the above code?

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Harbinger
  • 762
  • 2
  • 14
  • 36
  • Side bit - why you are invoking cat there too rather than just `wc -l filePath`? –  Dec 08 '14 at 06:26
  • 2
    @MichaelT bcoz I just want the number of lines. wc -l filepath returns line no with the file name. – Harbinger Dec 08 '14 at 06:28
  • 3
    While I'm not going to say its *wrong*, you might be interested in [How to get “wc -l” to print just the number of lines without file name?](http://stackoverflow.com/q/10238363/289086). It just seems a bit wasteful to invoke cat and stuff the entire file over the pipe (possibly quite expensive on large files) when you could instead do it operating on one line with the `cut` answer ([link](http://stackoverflow.com/a/16319483/289086)). –  Dec 08 '14 at 06:32

3 Answers3

3

I suggest you use a ProcessBuilder instead of Runtime.exec. You can also simplify your command by passing the filePath to wc. Please don't swallow Exception(s). Finally, you can use ProcessBuilder.inheritIO() (Sets the source and destination for subprocess standard I/O to be the same as those of the current Java process) like

String filePath = "/dir1/testFile.txt";
try {
    System.out.println("No: of lines : ");
    ProcessBuilder pb = new ProcessBuilder("wc", "-l", filePath);
    pb.inheritIO();
    Process p = pb.start();
    p.waitFor();
} catch (Exception e) {
    e.printStackTrace();
}

Of course, it's more efficient to count the lines in Java without spawning a new process. Perhaps like,

int count = 0;
String filePath = "/dir1/testFile.txt";
try (Scanner sc = new Scanner(new File(filePath));) {
    while (sc.hasNextLine()) {
        String line = sc.nextLine();
        count++;
    }
} catch (Exception e) {
    e.printStackTrace();
}
System.out.printf("No: of lines : %d%n", count);
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
2

When I execute the command directly

I doubt you're execute it "directly". You're probably running it in a shell.

Your code should run that script in a shell too.

rt.exec(new String[]("bash", "-c", findLineCount});
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
0

This is how i printed number of lines

public static void main(String[] args) {
        try {
            Runtime run = Runtime.getRuntime();
            String[] env = new String[] { "path=%PATH%;" + "your shell path " }; //path of  cigwin  bin or any similar application. this is needed only for windows  
            Process proc = run.exec(new String[] { "bash.exe", "-c", "wc -l < yourfile" }, env);
             BufferedReader reader = new BufferedReader(new InputStreamReader(        
                     proc.getInputStream()));                                          
                    String s;                                                                
                    while ((s = reader.readLine()) != null) {                                
                      System.out.println("Number of lines " + s);                             
                    }                                           

            proc.waitFor();
            int exitValue = proc.exitValue();
            System.out.println("Status {}" +  exitValue);


        }  catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } 
    }
Niraj Sonawane
  • 10,225
  • 10
  • 75
  • 104