0

To be clear: This question is not about how to parse arguments to the program like commons CLI/JCommando etc. does.

I would like to write Unix commands using Java. Although I don't want to write most of the stuff myself, I intend to use libraries and looking for your help to do so.

I found commons cli for parse arguments, like getopt. However I am looking for a last piece of library that works like Perl's diamond operator or Python's fileinput-library.

As unix commands (or GNU commands as I come from Linux) works is that after any flags have been parsed any arguments left are considered files. The command then loops through these files line by line, file by file. A dubble dash (e.g. git checkout -- myfile.txt) is there to separate filenames from arguments. If no arguments are left after parsing all arguments the program should read from standard in instead.

This is what Perl's diamond operator does as well as Python's fileinput library, on very very few lines:

Perl

@ARGV = ("diamond.pl", "stdin.pl");
while (<>) {
    print();
}

Python

import fileinput
for line in fileinput.input():
    process(line)

Is there a library in Java that does what these do as simple as they do it (a library that basically have the same API as https://docs.python.org/2/library/fileinput.html)? I don't want to write the stuff myself (look for arguments, if not loop through stdin otherwise load each file, preferably lazy, feed each line to the command etc)...I just want the business end, the loop like:

My idea

LineIterator li = new MagicTextLineFeeder(remainingAfterCommonsCliParsing);
for (String line : li.nextRow()) {
    System.out.println(line);
}

EDIT: Made it clear that I don't looking for another argument parsing library.

Aquaplanet
  • 563
  • 4
  • 14
  • For line-by-line reading, look at BufferedReader.readLine(). For command line arguments parsing, roll your own or search for "java command line parser" –  Nov 30 '15 at 13:19
  • There are a lot more cli related libraries than apache. Something in http://stackoverflow.com/questions/1200054/java-library-for-parsing-command-line-parameters maybe? But why don't you use perl or python? Java works okay-ish but it's simply not as nice as all others. – zapl Nov 30 '15 at 13:30
  • I don't know if I was not clear enough, but this post is not about argument parsing. There is as you say tons of libraries for that. This is about the step after that, traversing filenames left and feed the program the contents of the files. I would like to find a library with the same functionality as Python fileinput. Please read https://docs.python.org/2/library/fileinput.html Arkadiy: The question was if there is a library instead of rolling my own. I know I can use BufferedReader. zapl: Sure I can use Python or Perl, but I ask if there is a library for Java and NOT write my own. – Aquaplanet Nov 30 '15 at 13:47
  • 2
    I would not recommend writing UNIX commands using Java: a) deployment relies on non-POSIX dependencies. b) the startup times are horrible compared to non-byte code programs *without* offering an according advantage. c) There are high level languages better suited for the task, eliminating both a and b, like [Go](http://www.golang.org), which is statically compiled by default and you can literally just copy the executable from one Linux machine to any compatible (amd64 to amd64, for example) or from one BSD machine to the other. – Markus W Mahlberg Nov 30 '15 at 15:43
  • @MarkusWMahlberg I am trying to get Java my goto language and be so good that I can basically write "anything" without google too much, therefore not learning every single language. However you got very good arguments. – Aquaplanet Nov 30 '15 at 19:27
  • @Aquaplanet Granted. But wasn't there something like "do one job and do it *good*"? ;) Choose the right tool for the job. Java excels at business applications. Doing day to day admin tasks? Not so much. – Markus W Mahlberg Dec 01 '15 at 10:32

1 Answers1

1

Ah - the joys of Java 8:

http://howtodoinjava.com/2014/05/04/read-file-line-by-line-in-java-8-streams-of-lines-example/

private static void readStreamOfLinesUsingFiles() throws IOException
{
    Stream<String> lines = Files.lines(Paths.get("c:/temp", "data.txt"));
    Optional<String> hasPassword = lines.filter(s -> s.contains("password")).findFirst();
    if(hasPassword.isPresent()){
        System.out.println(hasPassword.get());
    }
    //Close the stream and it's underlying file as well
    lines.close();
}

Combine this with Stream.of() (passing an array where ellipsis is required) and flatMap and you got what you need (see this for details).

Beware that error handling in stream may be pretty broken.

Community
  • 1
  • 1
  • This is good enough, it is probably just a few lines more to get what I want. Considering Markus comment above I start to understand why Java doesn't have the libraries that does what Python has in its standard library. – Aquaplanet Nov 30 '15 at 19:41