We’ll try to stay in the project root if possible.
Find all non-hidden files to know the file structure.
$ find -path './.*' -prune -o -type f -print
./Algo-init.iml
./out/production/Algo-init/fr/eql/ai114/algo/init/demo/_1_HelloWorld.class
./src/fr/eql/ai114/algo/init/demo/_1_HelloWorld.java
-
-prunereturns true for the chosen path and preventsfindfrom descending. -
-omeans OR, so the paths matching-prunewon’t pass through-o. -
-type fselects files, not folders. -
By default, AND is used to connect different conditions.
-
-printis needed here. It’s often omitted since it’s the default action.Without
-print,find -path './.*' -prune -o -type fis interpreted as
find . \(-path './.*' -prune -o -type f \) -print # WRONG!The above line will also print the current directory
., which is not something that we want.The
-printshould stay on the same side of-owith-type f.
Find all hidden files.
$ find -path './.*' -type f -print
./.gitignore
./.idea/.gitignore
./.idea/misc.xml
./.idea/modules.xml
./.idea/workspace.xml
We need to extract both the package name and the class name from the source code. It would be a good idea to use shell variables and substitutions to make the commands easier to type.
Extract the relative path of the Java source code file.
$ JAVA_SRC_RELPATH=$(find -name '*.java')
$ cat $JAVA_SRC_RELPATH
package fr.eql.ai114.algo.init.demo;
public class _1_HelloWorld {
public static void main(String[] args) {
// Impression simple
System.out.print("Hello World !");
// Impression avec saut de ligne
System.out.println("Hello World !");
}
}
If I find from ./src/ instead of ./, the output won’t begin with ./src.
That complicates the upcomining commands as we’re staying at the project’s root.
Extract the package name.
$ PKG=$(awk '/^package / { print $NF }' $JAVA_SRC_RELPATH | tr -d ';')
$ echo $PKG
fr.eql.ai114.algo.init.demo
awksearches lines in the source file starting frompackage, and print the last field (determined by the system’sIFS(input field separator)), then- trim the final semicolon
;(head -c -2would trim both;and the trailing newline\n). - Store it to the shell variable
PKG.
Extract the class name.
$ CLASS=$(echo ${JAVA_SRC_RELPATH##.*/} | cut -d '.' -f1)
$ echo $CLASS
_1_HelloWorld
- To keep the source file name only, trim the path of the folder containing
that file by a greedy search for
.*/, then use##enclosed with${}for shell substitution, so that we have_1_HelloWorld.java. - Split this string into two fields using
cutwith the delimiter-d '.', and select the first field using-f1. - Store it to the shell variable
CLASS.
Execute the program.
$ cd out/production/Algo-init/
$ java $PKG.$CLASS
Hello World !Hello World !
A more in-depth analysis of the output with hexdump. Unluckily, it doesn’t
come with Git Bash, so we’ll add a bunch of options to od so that od
imitates the behavior of hexdump.
$ java $PKG.$CLASS | od -A x -t x1z -v
000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 21 48 65 6c >Hello World !Hel<
000010 6c 6f 20 57 6f 72 6c 64 20 21 0d 0a >lo World !..<
00001c
$ java $PKG.$CLASS | od -A x -t x1 -c
000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 21 48 65 6c
H e l l o W o r l d ! H e l
000010 6c 6f 20 57 6f 72 6c 64 20 21 0d 0a
l o W o r l d ! \r \n
00001c
$ java $PKG.$CLASS | od -A x -t x -c
000000 6c6c6548 6f57206f 20646c72 6c654821
H e l l o W o r l d ! H e l
000010 57206f6c 646c726f 0a0d2120
l o W o r l d ! \r \n
00001c
$ java $PKG.$CLASS | od -A d -t x1 -c
0000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 20 21 48 65 6c
H e l l o W o r l d ! H e l
0000016 6c 6f 20 57 6f 72 6c 64 20 21 0d 0a
l o W o r l d ! \r \n
0000028
Explanation of the four commands:
odgiveshexdump-like output. I’m not satisfied with this because I don’t see what\rand\nare.- I replaced
zin-t x1zby-c, so that below the hexadecimals-t x1, we have the printable characters and escape characters-c. - To see why
1in-t x1zis needed, I’ve taken it away, and in the hex code display, we observe that the output is grouped into blocks of 4-byte unit, then inverted before being transcoded into hexadecimals. For example,- at the beginning,
H,el,lcorrespond to hexadecimals48,65,6cand6crespectively. - The order of these four characters is reversed to give
l,l,e,H, which correspond to6c,6c,65and48. - The previous sequence of four hexadecimals are concatenated to give
6c6c6548in the first line ofod’s output.
- at the beginning,
- I changed
-A xto-A d, so the the leftmost column becomes a decimal number. Observe that 1C₁₆ = 1 × 16 + 12 × 1 = 28.
References:
- How to use ‘-prune’ option of ‘find’ in sh? on Stack Overflow
- Find command: 15 examples to exclude on the Unix School