//Cleaning Bash History using a Java 11 Single-File Sourcecode Program

Java 11 adds with JEP330 the ability to launch a Java source file directly from the command line without requiring to explicitly compile it. I can see this feature being convenient for some simple scripting or quick tests. Although Java isn't the most concise language it still has the benefit of being quite readable and having powerful utility APIs.

The following example reads the bash shell history from a file into a LinkedHashSet and only keeps the last recently used line if duplicates exist, essentially cleaning up the history.


import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashSet;

public class HistoryCleaner {

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

        Path path = Path.of(System.getProperty("user.home")+"/.bash_history");

        LinkedHashSet<String> deduplicated = new LinkedHashSet<>(1024);
        Files.lines(path).forEachOrdered(line -> {
            deduplicated.remove(line);
            deduplicated.add(line);
        });

        Files.write(path, deduplicated);
    }

}

duke@virtual1:~$ java HistoryCleaner.java

will compile and run the "script".


Shebangs are supported too

#!/usr/bin/java --source 11

import java.io....
However, since this is not part of the java language specification, single-file java programs (SFJP) with a #! are technically no regular java files and will not compile when used with javac. This also means that the common file naming conventions are not required for pure SFJPs - using a different file extension is advised. We can't call it .js - so lets call it .sfjp :).
duke@virtual1:~$ ./HistoryCleaner.sfjp
Will compile and run the HistoryCleaner SFJP containing the shebang declaration in the first line. Keeping the .java file extension would result in a compiler error.


Post a Comment:
  • HTML Syntax: NOT allowed