【问题标题】:rename the file according PDF title根据 PDF 标题重命名文件
【发布时间】:2016-07-03 16:49:44
【问题描述】:

我正在尝试编写文件重命名 Perl 脚本,以减少手动操作。我手动打开pdf文件,复制标题并根据标题重命名文件名。

我正在编写以下代码以根据文件标题重命名 pdf。例如SPE-180024-MS 是标题,pdf 应该重命名为那个

按照我的逻辑应该重命名文件,但是输出不正确

#!/usr/bin/perl

use strict;
#use warnings;

use Cwd;
use File::Basename;
#use File::Copy;
use File::Find;
use PDF::API2;
use CAM::PDF;

my $path1 = getcwd;
open( F6, ">Ref.txt" );

opendir( DIR, $path1 ) or die $!;
my @dots = grep /(.*?)\-(MS)$/, readdir(DIR);
closedir(DIR);

my @file;
my @files;
my $check;
my $err_1;
my $err_2;
my $err_3;

foreach my $file (@dots) {

    #print F6 $file."\n";
    opendir DIR1, $file or die "Can't open $file: $!";
    my @files = sort grep { -f "$file/$_" } readdir DIR1;
    my $data1 = join( ",", <@files> );
    closedir DIR1;

    #print F6 @files."\n";
    my $a = @files;

    if ($data1 =~ m#(((\w+)\-(\d+)\-MS)\.(pdf))#
        #&& $data1=~m#((\w+)\-(\d+)\-MS\.(xml))#) #((.*?)\.xml)#
        ) {

        my $check = $2;

        #print F6 $1."\n";

        if ( $data1 =~ m#(((\w+)\-(\d+)\-MS)\.(xml))# ) {
            my $check1 = $2;
            my $first  = $1;

            if ( $check eq $file || $check1 eq $file ) {

            }
            else {
                #print F6 $file."\tDIFFERENT FILE PRESENT\n";
            }
        }
    }

    foreach my $f1 ( glob("$file/*.xml") ) {

        #print F6 $f1."\n";

        open( FH, '<', $f1 ) or die "Cannot open file: $f1";
        my $data2 = join( "", <FH> );

        #print F6 $data2."\n";

        close FH;

        if ( $data2 =~ m#(<page-count count="(\d+)"/>)# ) {

            my $page = $2;

            #print F6 $f1."\t".$1."\n";

            if ( $f1 =~ m#(.*?)-MS/((.*?)-MS)#s
                #SPE-173391-MS/SPE-173393-MS    #(.*?)\.(.*?)$/s)
                ) {

                my $f11 = $2;

                #print F6 $f11."\n";
                if ( $file eq $f11 ) {

                }
                else {

                    $err_1
                        = $err_1
                        . $file . "\t"
                        . $f11
                        . "\tDIFFERENT XML FILE PRESENT\n";

                    #print F6 $file."\t".$f11."\tDIFFERENT XML FILE PRESENT\n";
                    #print F6 $file."\tDIFFERENT XML FILE PRESENT\n";
                }

                foreach my $f2 ( glob("$file/*.pdf") ) {

                    open( F2, "<$f2" ) or die "Cannot open file: $f2";
                    my $data = join( "", <F2> );
                    close F2;

                    my $xml_list = $data;

                    my $pdf   = PDF::API2->open($f2);
                    my $pages = $pdf->pages;

                    #print F6 $f2."\t".$pages."\n";

                    if ($f2 =~ m#(.*?)-MS/((.*?)-MS)#

                        #/(.*?)\.(.*?)$/s
                        ) {

                        my $f21 = $2;

                        if ( $file eq $f21 ) {

                        }
                        else {

                            $err_2
                                = $err_2
                                . $file . "\t"
                                . $f21
                                . "\tDIFFERENT PDF FILE PRESENT\n";

                            #print F6 $file."\t".$f21."\tDIFFERENT PDF FILE PRESENT\n";
                        }

                        while ( $f11 =~ m/$f21/gs ) {

                            if ( $page !~ m#$pages#s ) {

                                $err_3
                                    = $err_3
                                    . $f1 . "\t"
                                    . $page . "\t"
                                    . $f2 . "\t"
                                    . $pages . "\n";

                                #print F6 $f1."\t".$page."\t".$f2."\t".$pages."\n";

                                $data2 =~ s#<page-count count="$page"\/>#<page-count count="$pages"\/>#gs;

                                open( FH, '>', $f1 ) or die "Cannot open file: $f1";
                                print FH $data2 . "\n";
                                close FH;
                            }
                        }
                    }
                }
            }
        }
    }
}

close F6;

这是文件。标记的标题是我想要的。

【问题讨论】:

  • pdf 中的内容流可能会被过滤(这通常意味着它被压缩),因此您不能只使用正则表达式来查找标题(它不是“纯文本”形式因此它不会匹配或匹配将是pdf的一些随机部分)。要确认在一些类似记事本的编辑器中打开 pdf 并搜索标题 - 您可能找不到它。您需要正确解析 pdf 以获取第一页的内容,然后从中提取标题。我没有使用 perl 的经验,所以对此无能为力,抱歉。
  • 感谢您提供信息,但任何人都可以帮助生成代码以正常工作
  • 你可以使用工具pdfinfo(它是poppler工具包的一部分)告诉你PDF的标题吗?
  • 你能多解释一下你所说的标题是什么意思吗?那是文档顶部的一些文本标题,还是文件中的元信息?也许在 PDF 查看器中截取文件的屏幕截图,使敏感的内容不可读,然后在您想要的部分周围手绘一个圆圈。
  • 感谢 mark 和 simbabque,我没有使用任何工具,我正在创建脚本来查找 pdf 顶部的 pdf 文件的标题(例如:SPE-180024-MS)并替换文件根据那个标题

标签: perl pdf rename batch-rename


【解决方案1】:

PDF 通常有一堆元数据,其中包括文档标题。如果幸运的话,您会在其中找到所需的 PDF 标题。使用PDF::API2 及其info 方法的Perl 示例:

use autodie;
use Modern::Perl;
use PDF::API2;

my $file     = '/your/sample/file.pdf';
my $pdf      = PDF::API2->open( $file );
my %pdf_info = $pdf->info;
my $title    = $pdf_info{Title};

my $renamed_dir = '/some/where/else/';
if ( $title ) {
    my $new_name = $renamed_dir . $title;
    if ( -f $new_name ) {
        warn "File $new_name already exists, move it out of the way!";
    } else {
        $pdf->saveas( $new_name );
    }
} else {
    warn "No title found in document info.";
}

如果您需要使用文本的某些部分,则应先将其转换为文本。由于您没有提及任何操作系统限制,因此您获得了 Debian/Ubuntu 解决方案。首先,安装包poppler-utils。然后使用新安装的工具pdftotext从PDF中提取所有文本。使用pdftotext -layout 可能是个好主意。从结果文本中,您必须使用“标题”对行进行 grep/解析,然后使用它来重命名(或更安全:复制)PDF。

【讨论】:

  • 我从发布的图片中假设 OP 不是在“标题”元数据中寻找标题,而是在文档的文本中寻找标题
  • 这一行(例如 SPE-180024-MS)在每个文件中都包含常见的文本“MS”,说明我为什么要应用 grep 命令并替换它
【解决方案2】:

您不能只打开一个 PDF 文件并对其进行操作。它与文本文件不同,因此必须对其进行解析。 您可以使用CAM::PDF。它会将您的 pdf 转换为文本,以后可以对其进行分析以获取标题。

上面提供的链接涵盖了足够的内容来完成您的工作。我在这里复制了一些相关的东西

use CAM::PDF;
my $pdf = CAM::PDF->new('test1.pdf');
$pageNum = 1
my $page1 = $pdf->getPageContent(pageNum);

变量page1 将具有pageNum 变量指定的页面内容。休息是提取所需信息的问题。

如果您发现将整个 pdf 转换为文本,则可以使用 getpdftext.pl,它是 CAM::PDF 的一部分,但与阅读单页相比效率低下。

【讨论】:

  • 感谢 sharad 提供的信息,你能帮我改进我的代码吗
  • 提取文本并搜索标题听起来是个不错的主意。我不确定 PDF::Parse 虽然。它最后一次更新是在 2000 年,可能无法使用当前版本的 PDF 标准,尤其是压缩文件。
  • @sagarmore:浏览 CAM::PDF 文档并尝试一下。它能够读取您想要的页码并在页面中操作日期
  • 如果文件的标题遵循某种模式(看起来像那样),那么解析出来将非常简单。
  • 感谢 info.but 它是否可以应用于多个文件?
猜你喜欢
  • 2011-03-25
  • 2019-07-19
  • 2013-06-19
  • 2020-09-11
  • 1970-01-01
  • 2015-02-01
  • 1970-01-01
  • 2023-03-29
  • 2019-06-11
相关资源
最近更新 更多