Last active
August 28, 2024 18:07
-
-
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).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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