Exploration of My First IntelliJ Project

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
  • -prune returns true for the chosen path and prevents find from descending.

  • -o means OR, so the paths matching -prune won’t pass through -o.

  • -type f selects files, not folders.

  • By default, AND is used to connect different conditions.

  • -print is needed here. It’s often omitted since it’s the default action.

    Without -print,

    find -path './.*' -prune -o -type f
    

    is 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 -print should stay on the same side of -o with -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
  1. awk searches lines in the source file starting from package , and print the last field (determined by the system’s IFS (input field separator)), then
  2. trim the final semicolon ; (head -c -2 would trim both ; and the trailing newline \n).
  3. Store it to the shell variable PKG.

Extract the class name.

$ CLASS=$(echo ${JAVA_SRC_RELPATH##.*/} | cut -d '.' -f1)
$ echo $CLASS
_1_HelloWorld
  1. 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.
  2. Split this string into two fields using cut with the delimiter -d '.', and select the first field using -f1.
  3. 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:

  1. od gives hexdump-like output. I’m not satisfied with this because I don’t see what \r and \n are.
  2. I replaced z in -t x1z by -c, so that below the hexadecimals -t x1, we have the printable characters and escape characters -c.
  3. To see why 1 in -t x1z is 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,
    1. at the beginning, H, e l, l correspond to hexadecimals 48, 65, 6c and 6c respectively.
    2. The order of these four characters is reversed to give l, l, e, H, which correspond to 6c, 6c, 65 and 48.
    3. The previous sequence of four hexadecimals are concatenated to give 6c6c6548 in the first line of od’s output.
  4. I changed -A x to -A d, so the the leftmost column becomes a decimal number. Observe that 1C₁₆ = 1 × 16 + 12 × 1 = 28.

References:

  1. How to use ‘-prune’ option of ‘find’ in sh? on Stack Overflow
  2. Find command: 15 examples to exclude on the Unix School

No comment

Your email address will not be published. Required fields are marked *.