Pregunta

Tengo un montón de archivos PDF y mi programa Perl necesita hacer una búsqueda de texto completo para devolver cuáles contienen una cadena específica. Hasta la fecha he estado usando esto:

my @search_results = `grep -i -l \"$string\" *.pdf`;

donde $ cadena es el texto a buscar. Sin embargo, esto falla para la mayoría de los pdf porque el formato del archivo obviamente no es ASCII.

¿Qué puedo hacer que sea más fácil?

Aclaración: Hay alrededor de 300 pdf's cuyo nombre no sé de antemano. PDF :: Core es probablemente una exageración. Estoy tratando de hacer que pdftotext y grep jueguen bien entre ellos dado que no sé los nombres de los archivos PDF, todavía no puedo encontrar la sintaxis correcta.

Solución final usando la sugerencia de Adam Bellaire a continuación:

@search_results = `for i in \$( ls ); do pdftotext \$i - | grep --label="\$i" -i -l "$search_string"; done`;
¿Fue útil?

Solución

El hilo de PerlMonks aquí habla sobre este problema.

Parece que para su situación, podría ser más sencillo obtener pdftotext (la herramienta de línea de comandos), luego puede hacer algo como:

my @search_results = `pdftotext myfile.pdf - | grep -i -l \"$string\"`;

Otros consejos

Segundo solución de Adam Bellaire. Utilicé la utilidad pdftotext para crear un índice de texto completo de mi biblioteca de libros electrónicos. Es algo lento pero hace su trabajo. En cuanto al texto completo, pruebe PLucene o KinoSearch para almacenar el índice de texto completo.

Mi biblioteca, CAM :: PDF , tiene soporte para extraer texto, pero es un problema inherentemente difícil dada la orientación gráfica de la sintaxis de PDF. Entonces, el resultado es a veces galimatías. CAM :: PDF incluye un programa getpdftext.pl , o puede invocar la funcionalidad de esta manera:

my $doc = CAM::PDF->new($filename) || die "$CAM::PDF::errstr\n";
for my $pagenum (1 .. $doc->numPages()) {
   my $text = $doc->getPageText($pagenum);
   print $text;
}

Es posible que desee consultar PDF :: Core .

El índice / búsqueda de texto completo más fácil que he usado es mysql. Simplemente inserte en la tabla con el índice apropiado. Debe dedicar un tiempo a calcular las ponderaciones relativas de los campos (una coincidencia en el título puede tener una puntuación más alta que una coincidencia en el cuerpo), pero todo esto es posible, aunque con algunos sql peludos.

Plucene está en desuso (no ha habido ningún trabajo activo en él en los últimos dos años afaik) a favor de KinoSearch. KinoSearch creció, en parte, por entender las limitaciones arquitectónicas de Plucene.

Si tiene ~ 300 pdf, una vez que haya extraído el texto del PDF (suponiendo que el PDF tenga texto y no solo imágenes de texto) y dependiendo de los volúmenes de consulta, puede encontrar que grep es suficiente.

Sin embargo, sugeriría encarecidamente la ruta mysql / kinosearch, ya que han cubierto una gran cantidad de terreno (derivación, palabras vacías, ponderación de término, análisis de tokens) con el que no se beneficia al atascarse.

KinoSearch es probablemente más rápido que la ruta mysql, pero la ruta mysql le brinda una experiencia de desarrollador / software estándar más ampliamente utilizada. Y tienes la capacidad de usar el poder de SQL para aumentar tus consultas de búsqueda de texto libre.

Entonces, a menos que esté hablando de GRANDES conjuntos de datos y volúmenes de consultas insanas, mi dinero estaría en mysql.

Puedes probar Lucene (el puerto de Perl se llama Plucene). Las búsquedas son increíblemente rápidas y sé que PDFBox ya sabe cómo indexar archivos PDF con Lucene. PDFBox es Java, pero es probable que haya algo muy similar en algún lugar de CPAN. Incluso si no puede encontrar algo que ya agregue archivos PDF a un índice de Lucene, no debería ser más que unas pocas líneas de código para hacerlo usted mismo. Lucene le dará muchas más opciones de búsqueda que simplemente buscar una cadena en un archivo.

También hay una manera muy rápida y sucia. El texto en un archivo PDF se almacena realmente como texto sin formato. Si abre un PDF en un editor de texto o usa 'cadenas', puede ver el texto allí. La basura binaria suele ser fuentes incrustadas, imágenes, etc.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top