0

I was trying to run a unix command in java to overlook the double quotation mark in a parsed file:

    for(int i = 0; i < numTables; i++){
        try{
            String command = "sed -e \'s/\"/\"\"/g\' -e \'s/^/\"/\' -e \'s/$/\"/\' -e \'s/<>/\"<>\"/g\' input.dat > output.dat";
            Process p = Runtime.getRuntime().exec(command);
        } catch(IOException ioe){
            System.out.println("Error executing command");
        }
    }

However, typing the identical command on the terminal directly would work. Any idea what went wrong? Thank you!

Update: In fact, I tried the following (using array instead of just a String), it failed too:

            String[] command = new String[] {"sed", "-e", "\'s/\"/\"\"/g\'", "-e", "\'s/^/\"/\'", "-e", "\'s/$/\"/\'", "-e", "\'s/<>/\"<>\"/g\'", prefixedFileList.get(i), ">", fileList.get(i)};
            Process p = Runtime.getRuntime().exec(command);

Any thoughts?

As a clearer picture, the corresponding plain text that would be executed on unix terminal would be

sed -e 's/"/""/g' -e 's/^/"/' -e 's/$/"/' -e 's/<>/"<>"/g' input.dat > output.dat
5
  • 1
    How did it fail? Did you get an error, or simply nothing happened? Commented Oct 20, 2013 at 9:18
  • 1
    Get the process's output stream and print it. Possibly the error should be exposed there. Commented Oct 20, 2013 at 9:19
  • Looking for something like this? stackoverflow.com/questions/7134486/… Commented Oct 20, 2013 at 9:21
  • @Renan: Nothing happened Commented Oct 20, 2013 at 9:24
  • Perhaps you could go back and accept the answers to your previous questions. Commented Nov 20, 2013 at 1:06

3 Answers 3

0

Well in some special character you are not putting \ ? Can you put the same.

Sign up to request clarification or add additional context in comments.

Comments

0

It helps to distinguish exactly what a program argument is. When you execute this line:

sed -e 's/"/""/g' -e 's/^/"/' -e 's/$/"/' -e 's/<>/"<>"/g' input.dat > output.dat

The main method of the sed binary receives these strings in its argv:

  • sed
  • -e
  • s/"/""/g
  • -e
  • s/^/"/
  • -e
  • s/$/"/
  • -e
  • s/<>/"<>"/g
  • input.dat

Notice that the single-quotes (') are not part of the program arguments. The single-quotes are interpreted by the shell (bash, csh, etc.). They tell the shell not to evaluate or parse what's inside them. The shell takes a single-quoted string and passes it to the program as is, but the single-quotes are not part of the argument. They are for the benefit of the shell only.

Also notice that the file redirection, > output.dat, is not part of the program arguments. File redirection is parsed by the shell. It is not a program's job to know whether its standard output is being redirected; the program writes to standard output regardless, and the operating system performs the redirection. If you try to pass > output.dat as program arguments, sed will look for an additional input file named > and an additional input file named output.dat.

It is always better to call a Runtime.exec method which takes an array rather than a single String, as you seem to already know. Even better than that is to use the ProcessBuilder class, which can do output redirection, essentially duplicating the functionality of > in the shell:

ProcessBuilder builder = new ProcessBuilder(
    "sed",
    "-e",
    "s/\"/\"\"/g",
    "-e",
    "s/^/\"/",
    "-e",
    "s/$/\"/",
    "-e",
    "s/<>/\"<>\"/g",
    "input.dat");
builder.redirectOutput(new File("output.dat"));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);

Process p = builder.start();

3 Comments

This seems to be a pretty legitimate answer. However, when I tried, it still fails........... :(
How does it fail? Are you seeing an exception?
Try adding builder.redirectError(ProcessBuilder.Redirect.INHERIT); so any errors displayed by sed are visible in your program's output. I've updated my answer accordingly.
0

One of the best solutions it to use Apache Commons Exec library.

Below is my favourite usage :

CommandLine cmdLine = new CommandLine("AcroRd32.exe");
cmdLine.addArgument("/p");
cmdLine.addArgument("/h");
DefaultExecutor executor = new DefaultExecutor();
executor.setExitValue(1);
int exitValue = executor.execute(cmdLine);

We don't have to worry about encapsulating arguments properly using this form.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.