Skip to content

Instantly share code, notes, and snippets.

@ramayac
Last active August 28, 2024 18:07
Show Gist options
  • Save ramayac/8926162 to your computer and use it in GitHub Desktop.
Save ramayac/8926162 to your computer and use it in GitHub Desktop.
Simple and personal implementation for making Grep on zip files in a folder, this is specialy useful for massive log searches. I'm trying to keep it in a single file (yes, it's on purpose!!! and smaller than 1000 loc).
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class Main {
private static final float version = 1.4f;
private static final String CONST_ASTERIX = "-all";
// private static final String PARAM_DEBUG = "-d";
private static final String PARAM_SILENT = "-s";
private static final String MESSAGE_USO = "Uso: java -jar Grep.jar regex ext|-all [1] [-s]";
private static final String JAR_FILENAME = "Grep.jar";
private static Set<String> excludeSet = new HashSet<String>();
private static Set<File> subArchivosSet = new HashSet<File>();
// propiedades/flags
private static boolean flag_beVerbose = true;
private Logger L = new Logger();
public Main() throws IOException {
L = new Logger();
L.log("****************************************");
L.log("* *");
L.log("* Java Grep, version " + version + " *");
L.log("* *");
L.log("* Autor: Rodrigo Amaya, @ramayac, 13 *");
L.log("****************************************");
L.log();
}
public void ejecutar(String[] args) throws IOException,
InterruptedException, NumberFormatException {
if (args == null || args.length == 0) {
System.err.println(MESSAGE_USO);
return;
}
int swargs = args.length;
String regex = null, ext = null, silent = null;
Integer lines = null;
switch (swargs) {
case 0:
case 1:
System.err.println(MESSAGE_USO);
return;
case 2:
regex = args[0];
ext = args[1];
lines = 1;
silent = null;
break;
case 3:
regex = args[0];
ext = args[1];
lines = Integer.parseInt(args[2]);
silent = null;
break;
case 4:
regex = args[0];
ext = args[1];
lines = Integer.parseInt(args[2]);
silent = args[3];
break;
default:
System.err.println(MESSAGE_USO);
return;
}
if (regex == null || regex.trim().isEmpty()) {
System.err
.println("Falta la expresión regular o la cadena a buscar");
return;
}
if (ext == null || ext.trim().isEmpty()) {
System.err.println("Falta la extension de archivo");
return;
} else if (ext.equals(CONST_ASTERIX)) {
System.err
.println("ADVERTENCIA: Se tomarán todos los archivos encontrados");
}
if (lines == null || lines <= 0) {
System.err.println("Las lineas deben ser > 1.");
}
if (silent != null && silent == PARAM_SILENT) {
flag_beVerbose = false;
L.setBeVerbose(flag_beVerbose);
}
// Busqueda de multiples archivos en la carpeta actual...
File currentFolder = new File(".");
if (currentFolder.isDirectory()) {
// Primero fichamos todos los "ficheros", get it? lol.
despliegueRecursivo(currentFolder, ext);
} else {
System.err
.println("El parametro 'ruta' debe ser un directorio no un archivo.");
return;
}
if (subArchivosSet == null || subArchivosSet.isEmpty()) {
System.err
.println("No hay archivos que revisar, revisa el filtro ("
+ ext + ").");
System.err.println("El directorio usado fue: "
+ currentFolder.getAbsolutePath());
return;
}
long inicio = System.currentTimeMillis();
L.log("Inicia la busqueda de '" + regex + "', VERBOSE: "
+ (L.isVerbose() ? "ON" : "OFF") + ", lineas : " + lines);
Lector lect1 = new Lector(regex, excludeSet, L, lines);
Thread t1;
for (Iterator<File> iterator = subArchivosSet.iterator(); iterator
.hasNext();) {
File f = (File) iterator.next();
lect1.setFile(f);
t1 = new Thread(lect1);
t1.start();
t1.join();
lect1.resetEjecucion();
}
// Lector lect2 = new Lector(regex, excludeSet, L);
// Threads Artesanales
/*
* Thread t1, t2;
*
* for (Iterator<File> iterator = subArchivosSet.iterator();
* iterator.hasNext();) { File f = (File) iterator.next();
*
* lect1.setFile(f); t1 = new Thread(lect1); t1.start();
*
* if(iterator.hasNext()){ lect2.setFile((File) iterator.next()); t2 =
* new Thread(lect2); t2.start();
*
* t2.join(); lect2.resetEjecucion(); }
*
* t1.join(); lect1.resetEjecucion();
*
* }
*/
long fin = System.currentTimeMillis() - inicio;
L.log("\n\rFin (" + fin + " milis)");
}
void close() throws IOException {
L.close();
}
void despliegueRecursivo(File folder, final String ext) {
despliegueRecursivo(folder, subArchivosSet, ext);
}
void despliegueRecursivo(File folder, final Collection<File> archivos,
final String ext) {
// File[] listado = folder.listFiles(new ArchivoAceptado(ext));
File[] listado = folder.listFiles();
for (File f : listado) { // file or folder?
if (f.isDirectory()) {
despliegueRecursivo(f, ext);
} else {
// Es archivo!
// System.out.println(f.getName());
String aux = f.toString();
if (aux.contains(L.getFilename()) || aux.contains(JAR_FILENAME)) {
continue;
}
if (ext.equals(CONST_ASTERIX)) {
archivos.add(f);
} else if (ext.equals(CONST_ASTERIX) == false
&& aux.contains(ext)) {
archivos.add(f);
}
}
}
}
public static void main(String[] args) {
try {
Main main = new Main();
main.ejecutar(args);
main.close();
} catch (IOException ioe) {
System.err.println(ioe.getMessage());
} catch (InterruptedException ie) {
System.err.println(ie.getMessage());
}
}
}
class Logger {
private FileWriter fw = null;
private BufferedWriter bw = null;
private boolean beVerbose = true;
private String filename;
public String getFilename() {
return filename;
}
public Logger() throws IOException {
filename = "out.txt";
fw = new FileWriter(new File(filename));
bw = new BufferedWriter(fw);
}
public void log() throws IOException {
if (isVerbose())
System.out.println();
bw.append("\n");
bw.append("\r");
}
public void log(final String msg) throws IOException {
/* if(isVerbose()) */System.out.println(msg);
bw.append(msg);
bw.append("\r");
}
public void close() throws IOException {
if (bw != null) {
bw.close();
}
if (fw != null) {
fw.close();
}
}
public void flush() throws IOException {
bw.flush();
fw.flush();
}
public boolean isVerbose() {
return beVerbose;
}
public void setBeVerbose(boolean beSilent) {
this.beVerbose = beSilent;
}
}
class Lector implements Runnable {
private Grep grep;
private Logger L;
private File f;
private Integer lines;
private boolean ejecutado = false;
public boolean isEjecutado() {
return ejecutado;
}
public void resetEjecucion() {
ejecutado = false;
}
public File getFile() {
return f;
}
public void setFile(final File f) {
this.f = f;
grep.resetLine();
}
public Lector(String regex, Set<String> excludeSet, final Logger log,
Integer lines) {
grep = new Grep();
grep.compile(regex);
grep.setExcludeList(excludeSet);
L = log;
this.lines = lines;
// grep.resetLine();
}
boolean match(String line, boolean grepsearch) throws IOException {
if(line == null || line.isEmpty()) return false;
grep.addLine();
String aux;
if(grepsearch){
aux = grep.search(line);
} else {
aux = " " + grep.getFilename() + ":" + grep.getLine() + ":" + line;
}
if (aux != null && aux.isEmpty() == false) {
L.log(aux);
return true;
}
return false;
}
void read(File f) throws IOException {
grep.setFilename(f.getName());
FileInputStream fis = new FileInputStream(f);
Integer step;
BufferedReader reader = new BufferedReader(new InputStreamReader(fis,
Grep.ENCODING_TXT));
for (String line; (line = reader.readLine()) != null;) {
if(match(line, true)){
for (step = lines; step > 1; step--) {
match(reader.readLine(), false);
}
}
}
reader.close();
fis.close();
L.flush();
}
void readZip(File f) throws IOException {
grep.setFilename(f.getName());
final ZipFile zipFile = new ZipFile(f);
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
// ZipInputStream zipInput = null;
Integer step;
while (entries.hasMoreElements()) {
final ZipEntry zipEntry = entries.nextElement();
if (!zipEntry.isDirectory()) {
final String fileName = zipEntry.getName();
if (L.isVerbose())
L.log("*** Revisando el archivo comprimido: '" + fileName
+ "' ***");
InputStream input = zipFile.getInputStream(zipEntry);
BufferedReader reader = new BufferedReader(
new InputStreamReader(input, Grep.ENCODING_TXT));
for (String line; (line = reader.readLine()) != null;) {
if(match(line, true)){
for (step = lines; step > 1; step--) {
match(reader.readLine(), false);
}
}
}
reader.close();
input.close();
}
}
zipFile.close();
L.flush();
}
boolean checkForZip(final File f) throws IOException {
if (f.getName().contains(".zip")) {
RandomAccessFile raf = new RandomAccessFile(f, "r");
long n = raf.readInt();
raf.close();
if (n == 0x504B0304) { // la magia papá!
// System.out.println("Archivo ZIP encontrado");
return true;
} else {
System.err.println(" El archivo especificado no es un ZIP ");
return false;
}
} else {
return false;
}
}
@Override
public void run() {
try {
if (L.isVerbose())
L.log("* Buscando en el archivo: '" + f.getAbsolutePath()
+ "' *");
if (checkForZip(this.f)) {
readZip(this.f);
} else {
read(this.f);
}
} catch (IOException x) {
System.err.println(f + ": " + x);
} finally {
ejecutado = true;
}
}
}
class Grep {
// Charset and decoder for ISO-8859-15
public static final String ENCODING_TXT = "ISO-8859-15";
// private static final String encoding_bin = "UTF-8";
// El patron que se esta buscando
private Pattern pattern;
private Set<String> excludeList = new HashSet<String>();
private Matcher pm = null;
private int line = 0;
private String filenam = "";
public void setExcludeList(final Set<String> excl) {
excludeList.addAll(excl);
}
public int getLine() {
return this.line;
}
public void setLine(int line) {
this.line = line;
}
public void addLine() {
this.line++;
}
public void resetLine() {
this.line = 0;
}
public String getFilename() {
return this.filenam;
}
public void setFilename(String filenam) {
this.filenam = filenam;
}
public void compile(final String pat) {
try {
pattern = Pattern.compile(pat);
} catch (PatternSyntaxException x) {
System.err.println(x.getMessage());
System.exit(1);
}
}
public String search(String str) {
for (String s : excludeList) {
if (s.contains(str))
return null;
}
if (pm == null) {
pm = pattern.matcher(str);
} else {
pm.reset(str);
}
if (pm.find()) {
return " " + getFilename() + ":" + getLine() + ":" + str;
}
return null;
}
}
class ArchivoAceptado implements FilenameFilter {
private String ext;
ArchivoAceptado(String ext) {
this.ext = ext;
}
@Override
public boolean accept(File dir, final String name) {
if (name.contains(this.ext))
return true;
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment