linux to compile multiple java file - linux

here is my directory structure.
/user/a
/user/b
/user/b
inside folder a,b,c there is a file person.java (it is the Same file, just a one line modification.
now, on my shell, im on my /user/ directory and i try to do
javac */person.java
the shell returns the following error,
person.java:14: duplicate class: person
Is there anything to resolve this?

I think the problem here might be, that javac tries to compile everything in one go, which naturally results in duplicated class definitions.
A simple way to resolve this would be
find . -name '*.java' -exec javac {} \;
Edit:
Or to be more precise find . -name 'person.java' -maxdepth 2 -exec javac {} \;

I would go for the small shell script:
for f in */person.java; do
javac $file
done
First line find all the files person.java in a sub-directory, second line compile the file.

Related

Changing file extension within the file command

I am using the following command to find files, zip them up and delete the original file:
find data/* -type f -execdir zip '{}'.zip '{}' \; -delete
At the moment if a file called "something.txt" is found a zip file called "something.txt.zip" is created. How do I make the filename "something.zip" instead?
I know in bash I can do something like ${x:.*} but I cannot seem to get something like this working here.
This seems to work but it is a bit of a fudge:
find data/* -execdir bash -c 'zip -j "${1%.*}.zip" "${1}"' _ {} \;
I would love to see something cleaner.

find and remove multiple file using linux command

I have a directory named classes which contains a lot of sub-directories -
classes
|-security
|-registration
|-service
....
Each of these directory contains a lot of java files and their compiled classes files. I want to remove all the class file.
Going to classes directory I can list out all the class file using find command -
$ find . -name *.class
Is there any command in linux to remove all the classes file under the classes directory.
The usual answer uses the -exec option of find:
find . -name "*.class" -exec rm {} \;
Be sure to quote the wildcard, to ensure that it is passed into find (rather than globbed by the shell, first).
For further discussion, see these questions:
Command line: piping find results to rm
Linux why can't I pipe find result to rm?
Use xargs with pipe lining -
$ find . -name *.class | xargs rm *

Copy specific files recursively

This problem has been discussed extensively but I couldn't find a solution that would help me.
I'm trying to selectively copy files from a directory tree into a specific folder. After reading some Q&A, here's what I tried:
cp `find . -name "*.pdf" -type f` ../collect/
I am in the right parent directory and there indeed is a collect directory a level above. Now I'm getting the error: cp: invalid option -- 'o'
What is going wrong?
To handle difficult file names:
find . -name "*.pdf" -type f -exec cp {} ../collect/ \;
By default, find will print the file names that it finds. If one uses the -exec option, it will instead pass the file names on to a command of your choosing, in this case a cp command which is written as:
cp {} ../collect/ \;
The {} tells find where to insert the file name. The end of the command given to -exec is marked by a semicolon. Normally, the shell would eat the semicolon. So, we escape the semicolon with a backslash so that it is passed as an argument to the find command.
Because find gives the file name to cp directly without interference from the shell, this approach works for even the most difficult file names.
More efficiency
The above runs cp on every file found. If there are many files, that would be a lot of processes started. If one has GNU tools, that can be avoided as follows:
find . -name '*.pdf' -type f -exec cp -t ../collect {} +
In this variant of the command, find will supply many file names for each single invocation of cp, potentially greatly reducing the number of processes that need to be started.

Write a script in Linux to run make in every child directory maxdepth of 2

I am looking to write a script to go into each child directory (not recursively) and run a make file to create a binary. One way to do this is to change directories and run make for each folder but it's not very elegant and can be error prone if additional folders and files are added.
I have had a little success delving into child dirs with the following:
find -maxdepth 2 -type f -print -exec make {} . \;
I get the error for each dir which states the following:
make: Nothing to be done for reduc211/makefile.
Anyone got any ideas as to what I can change? Any help would be greatly appreciated!
Many thanks and happy coding.
make reduc211/makefile doesn't run the named makefile; it looks for a Makefile using make's lookup rules and tries to make the target reduc211/makefile. What you want is something like
find -maxdepth 2 -name 'Makefile' -print -execdir make \;
This runs the make command in every directory where a file named Makefile is found.
If you have differently named makefiles, for example each is of the form Makefile.something, you could try
find -maxdepth 2 -name 'Makefile.*' -print -execdir make -f \{}\ \;
to run make using the specific Makefiles found by find.
Something like this?
for dir in *; do
if [ -d "$dir" ]; then
(cd "$dir" && make)
fi
end

Running command recursively in linux

I'm trying to come up with a command that would run mp3gain FOLDER/SUBFOLDER/*.mp3 in each subfolder, but I'm having trouble understanding why this command doesn't work:
find . -type d -exec mp3gain \"{}\"/*.mp3 \;
When run, I get error Can't open "./FOLDER/SUBFOLDER"/*.mp3 for reading for each folder and subfolder.
If I run command manually with mp3gain "./FOLDER/SUBFOLDER"/*.mp3 it works. What's going wrong?
If you have a fixed data structure like
folder1/subfolder1/
folder1/subfolder2/
folder2/subfolder1/
[...]
and using zsh or bash version >=4.0 you could try
mp3gain **/*.mp3
But to make sure check the output of
ls **/*.mp3
before you are getting serious with mp3gain.
When you run mp3gain "./FOLDER/SUBFOLDER"/*.mp3 from your shell, the *.mp3 is getting expanded by the shell before being passed to mp3gain. When find runs it, there is no shell involved, and the *.mp3 is getting passed literally to mp3gain. The latter has no idea how to deal with wildcards (because normally it doesn't have to).
Hmmm. Just tried this to test how the directory is parsed by replacing mp3gain with echo and it works:
find . -type d -exec echo {}\/\*.mp3 \;
Try running your version of the command but with echo to see the file output for yourself:
find . -type d -exec echo \"{}\"/*.mp3 \;
Seems the quotes get in the way in your original command.
this works...
find /music -name *mp3 -exec mp3gain -r -k {} \;

Resources