commit
268736c6c7
@ -0,0 +1,24 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class Artifacts {
|
||||||
|
|
||||||
|
Tools tools = new Tools();
|
||||||
|
|
||||||
|
|
||||||
|
public MFile getMFile(File file) {
|
||||||
|
MFile mfile = new MFile();
|
||||||
|
mfile.file = file;
|
||||||
|
mfile.md5 = tools.getMd5(file.getPath());
|
||||||
|
return mfile;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MFile {
|
||||||
|
public File file;
|
||||||
|
public String md5;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.control.cell.PropertyValueFactory;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import app.Artifacts.MFile;
|
||||||
|
|
||||||
|
public class Controller {
|
||||||
|
|
||||||
|
|
||||||
|
Map<Integer, MFile> doubles;
|
||||||
|
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected Text loadDirState;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected Text calcMd5State;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected Text sortFileState;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected Text findDoubleState;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected Text delDoubleState;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected Text fileNr;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected Text doubleNr;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected TextField dir;
|
||||||
|
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected void loadDir() {
|
||||||
|
|
||||||
|
Task<Void> loadDirTask = new Task<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
|
||||||
|
loadDirState.setText("");
|
||||||
|
calcMd5State.setText("");
|
||||||
|
sortFileState.setText("");
|
||||||
|
findDoubleState.setText("");
|
||||||
|
delDoubleState.setText("");
|
||||||
|
fileNr.setText("Number of Files:");
|
||||||
|
doubleNr.setText("Number of Doubles:");
|
||||||
|
|
||||||
|
|
||||||
|
Path path = Paths.get(dir.getText());
|
||||||
|
|
||||||
|
if (!Files.isDirectory(path)) {
|
||||||
|
loadDirState.setText("ERROR.");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Map<Integer, File> pool = new Routines().loadPool(dir.getText(), "file");
|
||||||
|
new Write().textPool("pool", pool);
|
||||||
|
loadDirState.setText("OK.");
|
||||||
|
fileNr.setText("Number of Files: " + pool.size());
|
||||||
|
|
||||||
|
Map<Integer, MFile> md5Pool = new Routines().md5Pool(pool);
|
||||||
|
new Write().textMd5Pool("md5Pool", md5Pool);
|
||||||
|
calcMd5State.setText("OK.");
|
||||||
|
|
||||||
|
Map<Integer, MFile> qsMd5Pool = new QuicksortMd5().quicksortMd5(md5Pool);
|
||||||
|
new Write().textMd5Pool("qsMd5Pool", qsMd5Pool);
|
||||||
|
sortFileState.setText("OK.");
|
||||||
|
|
||||||
|
doubles = new Routines().doubles(qsMd5Pool);
|
||||||
|
new Write().textMd5Pool("doubles", doubles);
|
||||||
|
findDoubleState.setText("OK.");
|
||||||
|
doubleNr.setText("Number of Doubles: " + doubles.size());
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new Thread(loadDirTask).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected void deleteDoubles() {
|
||||||
|
|
||||||
|
Task<Void> delDoubleTask = new Task<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
|
||||||
|
for (int i = 0; i < doubles.size(); i++) {
|
||||||
|
new Execute().execute(new String[]{"rm", doubles.get(i).file.getAbsolutePath()});
|
||||||
|
|
||||||
|
}
|
||||||
|
delDoubleState.setText("OK.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new Thread(delDoubleTask).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
public class Execute {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param cmd an array representing a shell command
|
||||||
|
* @return <i>TwoBr</i> class, containing two BufferedReaders,
|
||||||
|
* <i>output</i> and <i>error</i>
|
||||||
|
* @see <i>output</i> BufferedReader, corresponds to STDOUT
|
||||||
|
* <i>error</i> BufferedReader, corresponds to STDERR
|
||||||
|
*/
|
||||||
|
public TwoBr execute(String cmd[]) {
|
||||||
|
TwoBr twobr = new TwoBr();
|
||||||
|
try {
|
||||||
|
Process process = Runtime.getRuntime().exec(cmd);
|
||||||
|
process.waitFor();
|
||||||
|
twobr.output = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
|
twobr.error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return twobr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TwoBr {
|
||||||
|
public BufferedReader output;
|
||||||
|
public BufferedReader error;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.layout.GridPane;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
|
||||||
|
public class Main extends Application {
|
||||||
|
|
||||||
|
static String foo;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) throws Exception{
|
||||||
|
Parent root = FXMLLoader.load(getClass().getResource("layout.fxml"));
|
||||||
|
Scene scene = new Scene(root, 300, 275);
|
||||||
|
|
||||||
|
|
||||||
|
primaryStage.setTitle("mucc");
|
||||||
|
primaryStage.setScene(scene);
|
||||||
|
primaryStage.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
launch(args);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import app.Artifacts.MFile;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class QuicksortMd5 {
|
||||||
|
private Map<Integer, MFile> md5Pool;
|
||||||
|
private int i;
|
||||||
|
private int j;
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
public Map<Integer, MFile> quicksortMd5(Map<Integer, MFile> md5Pool) {
|
||||||
|
this.md5Pool = md5Pool;
|
||||||
|
|
||||||
|
quicksort(0, md5Pool.size() - 1);
|
||||||
|
return this.md5Pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void quicksort(int low, int high) {
|
||||||
|
i = low;
|
||||||
|
j = high;
|
||||||
|
p = low + (high - low) / 2;
|
||||||
|
|
||||||
|
while (i < j) {
|
||||||
|
|
||||||
|
// a < b a.compareto(b) = -1
|
||||||
|
// a = b a.compareto(b) = 0
|
||||||
|
// a > b a.compareto(b) = 1
|
||||||
|
|
||||||
|
while (i < p) {
|
||||||
|
if (imd5().compareTo(pmd5()) <= 0) {
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
swap(i, p);
|
||||||
|
j = high;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (p < j) {
|
||||||
|
if (jmd5().compareTo(pmd5()) >= 0) {
|
||||||
|
j--;
|
||||||
|
} else {
|
||||||
|
swap(p, j);
|
||||||
|
i = low;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (high - p > 2) {
|
||||||
|
quicksort(p, high);
|
||||||
|
}
|
||||||
|
if (p - low > 2) {
|
||||||
|
quicksort(low, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void swap(int a, int b) {
|
||||||
|
MFile temp = md5Pool.get(a);
|
||||||
|
md5Pool.put(a, md5Pool.get(b));
|
||||||
|
md5Pool.put(b, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String imd5() {
|
||||||
|
return md5Pool.get(i).md5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String jmd5() {
|
||||||
|
return md5Pool.get(j).md5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pmd5() {
|
||||||
|
return md5Pool.get(p).md5;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
### What is `mucc`?
|
||||||
|
`mucc` is an example for interactions between Linux, Java and JavaFX.
|
||||||
|
It is a tool for purging duplicates from
|
||||||
|
a filesystem.
|
||||||
|
|
||||||
|
It does this by calculating a hash of each file
|
||||||
|
and sorting the files by hash.
|
||||||
|
If two files have the same hash, the older file will be deleted.
|
||||||
|
|
||||||
|
It also displays some information about what is happening.
|
||||||
|
This ensures the user never suspects something went horribly wrong.
|
||||||
|
|
||||||
|
|
||||||
|
### Package Contents
|
||||||
|
|
||||||
|
| Class | Description |
|
||||||
|
|---------------|-------------|
|
||||||
|
| Artifacts | Simple objects used by other classes.|
|
||||||
|
| Controller | JavaFX class containing application logic. |
|
||||||
|
| Execute | Issues shell commands.|
|
||||||
|
| layout.fxml | Contains layout data.|
|
||||||
|
| Main | Main JavaFX class. Run from here.|
|
||||||
|
| QuicksortMd5 | Quicksort algorithm.|
|
||||||
|
| README.md | You are here.|
|
||||||
|
| Routines | Higher level routines called by Controller.|
|
||||||
|
| Tools | Simple tools.|
|
||||||
|
| Write | Writes to /tmp. Used for data storage.|
|
||||||
|
|
||||||
|
|
||||||
|
### Issues and Features
|
||||||
|
- Add proper directory selection.
|
||||||
|
- Fix issues where nested duplicates would not be deleted on first pass.
|
||||||
|
- Make UI prettier.
|
||||||
|
- Make code prettier.
|
||||||
|
|
@ -0,0 +1,92 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import app.Artifacts.MFile;
|
||||||
|
|
||||||
|
public class Routines {
|
||||||
|
|
||||||
|
|
||||||
|
Execute x = null;
|
||||||
|
|
||||||
|
Tools tools = new Tools();
|
||||||
|
Write write = new Write();
|
||||||
|
|
||||||
|
|
||||||
|
public Routines() {
|
||||||
|
this.x = new Execute();
|
||||||
|
|
||||||
|
this.tools = new Tools();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [1] Write output of <b>find srcdir</b> to <b>/tmp/find</b> <br>
|
||||||
|
* [2] Read <b>/tmp/find</b> into <b>List>String></b> <br>
|
||||||
|
* [3] Add <b>List>String></b> entries to <b>Map>String,File></b> , where
|
||||||
|
* <b>String</b> is an <b>int</b> key. <br>
|
||||||
|
*
|
||||||
|
* @param srcdir
|
||||||
|
* @param type file OR directory
|
||||||
|
* @return filepool
|
||||||
|
*/
|
||||||
|
public Map<Integer, File> loadPool(String srcdir, String type) {
|
||||||
|
// [1]
|
||||||
|
x.execute(new String[]{System.getProperty("user.dir") + "/src/app/toFile.sh", "find", srcdir, "/tmp/find"});
|
||||||
|
// [2]
|
||||||
|
List<String> lines = null;
|
||||||
|
try {
|
||||||
|
lines = Files.readAllLines(Paths.get("/tmp/find"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// [3]
|
||||||
|
Map<Integer, File> filepool = new HashMap<Integer, File>();
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
|
File file = new File(lines.get(i));
|
||||||
|
if (type == "directory" && file.isDirectory() || type == "file" && file.isFile()) {
|
||||||
|
filepool.put(j, file);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filepool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<Integer, MFile> md5Pool(Map<Integer, File> pool) {
|
||||||
|
Map<Integer, MFile> md5Pool = new HashMap<>();
|
||||||
|
for (int i = 0; i < pool.size(); i++) {
|
||||||
|
File file = pool.get(i);
|
||||||
|
md5Pool.put(i, new Artifacts().getMFile(file));
|
||||||
|
}
|
||||||
|
return md5Pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<Integer, MFile> doubles(Map<Integer, MFile> md5Pool) {
|
||||||
|
Map<Integer, MFile> doubles = new HashMap<>();
|
||||||
|
int d = 0;
|
||||||
|
for (int i = 0; i < md5Pool.size() - 1; i++) {
|
||||||
|
MFile iF = md5Pool.get(i);
|
||||||
|
MFile jF = md5Pool.get(i + 1);
|
||||||
|
if (iF.md5.equals(jF.md5)) {
|
||||||
|
if (iF.file.lastModified() >= jF.file.lastModified()) {
|
||||||
|
doubles.put(d, iF);
|
||||||
|
d++;
|
||||||
|
} else {
|
||||||
|
doubles.put(d, jF);
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return doubles;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class Tools {
|
||||||
|
|
||||||
|
Execute x;
|
||||||
|
|
||||||
|
public Tools() {
|
||||||
|
x = new Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Md5 of File at @param path
|
||||||
|
*/
|
||||||
|
public String getMd5(String path) {
|
||||||
|
// output of md5sum: "md5 filepath"
|
||||||
|
BufferedReader md5reader = x.execute(new String[] { "md5sum", path }).output;
|
||||||
|
String md5 = null;
|
||||||
|
try {
|
||||||
|
md5 = md5reader.readLine().split(" ")[0];
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return md5;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package app;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.util.Map;
|
||||||
|
import app.Artifacts.MFile;
|
||||||
|
|
||||||
|
public class Write {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* writes <b>text</b> to file at <b>path</b>
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
|
public void textFile(String path, StringBuilder text) {
|
||||||
|
try {
|
||||||
|
BufferedWriter bw = new BufferedWriter(new FileWriter(new File(path)));
|
||||||
|
bw.write(text.toString());
|
||||||
|
bw.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append all elements of <b>pool</b> to StringBuilder and write to
|
||||||
|
* <b>/tmp/name</b>
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @param pool
|
||||||
|
*/
|
||||||
|
public void textPool(String name, Map<Integer, File> pool) {
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
for (int i = 0; i < pool.size(); i++) {
|
||||||
|
text.append(i + " " + pool.get(i) + "\n");
|
||||||
|
}
|
||||||
|
textFile("/tmp/" + name, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append all elements of <b>md5Pool</b> to StringBuilder and write to
|
||||||
|
* <b>/tmp/name</b>
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @param md5Pool
|
||||||
|
*/
|
||||||
|
public void textMd5Pool(String name, Map<Integer, MFile> md5Pool) {
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
for (int i = 0; i < md5Pool.size(); i++) {
|
||||||
|
text.append(i + " " + md5Pool.get(i).md5 + " " + md5Pool.get(i).file + "\n");
|
||||||
|
}
|
||||||
|
textFile("/tmp/" + name, text);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import java.lang.*?>
|
||||||
|
<?import java.util.*?>
|
||||||
|
<?import javafx.scene.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import java.net.*?>
|
||||||
|
<?import javafx.geometry.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.scene.text.*?>
|
||||||
|
|
||||||
|
|
||||||
|
<GridPane fx:controller="app.Controller"
|
||||||
|
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
|
||||||
|
<padding>
|
||||||
|
<Insets top="25" right="25" bottom="10" left="25"/>
|
||||||
|
</padding>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
text="Task"
|
||||||
|
GridPane.rowIndex="0"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<Text
|
||||||
|
text="State"
|
||||||
|
GridPane.rowIndex="0"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
text="Loading Directory."
|
||||||
|
GridPane.rowIndex="1"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text fx:id="loadDirState"
|
||||||
|
text=""
|
||||||
|
GridPane.rowIndex="1"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
text="Calculating Md5."
|
||||||
|
GridPane.rowIndex="2"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text fx:id="calcMd5State"
|
||||||
|
text=""
|
||||||
|
GridPane.rowIndex="2"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
text="Sorting Files."
|
||||||
|
GridPane.rowIndex="3"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text fx:id="sortFileState"
|
||||||
|
text=""
|
||||||
|
GridPane.rowIndex="3"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
text="Finding Doubles."
|
||||||
|
GridPane.rowIndex="4"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text fx:id="findDoubleState"
|
||||||
|
text=""
|
||||||
|
GridPane.rowIndex="4"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text
|
||||||
|
text="Deleting Doubles."
|
||||||
|
GridPane.rowIndex="5"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text fx:id="delDoubleState"
|
||||||
|
text=""
|
||||||
|
GridPane.rowIndex="5"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<TextField fx:id="dir"
|
||||||
|
text="Select Directory."
|
||||||
|
GridPane.rowIndex="6"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<Button text="Load"
|
||||||
|
GridPane.rowIndex="6"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
onAction="#loadDir"/>
|
||||||
|
|
||||||
|
|
||||||
|
<Text fx:id="fileNr"
|
||||||
|
text="Number of Files:"
|
||||||
|
GridPane.rowIndex="7"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Text fx:id="doubleNr"
|
||||||
|
text="Number of Doubles:"
|
||||||
|
GridPane.rowIndex="8"
|
||||||
|
GridPane.columnIndex="0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<Button text="Delete"
|
||||||
|
GridPane.rowIndex="8"
|
||||||
|
GridPane.columnIndex="1"
|
||||||
|
onAction="#deleteDoubles"/>
|
||||||
|
|
||||||
|
|
||||||
|
</GridPane>
|
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
a=$1
|
||||||
|
b=$2
|
||||||
|
c=$3
|
||||||
|
|
||||||
|
$a $b > $c
|
Loading…
Reference in new issue