根据DB中的值重命名文件

时间:2020-11-29 10:32:29

I am very new to Perl and I need to complete a project that is going to rely on it. I need to take pictures that are in a folder, look up their name in a DB and then rename the picture based on another value in that row.

我是Perl的新手,我需要完成一个依赖它的项目。我需要拍摄文件夹中的图片,在DB中查找其名称,然后根据该行中的其他值重命名图片。

So say I need to rename the picture

所以说我需要重命名图片

010300000000001002.jpg

I need to then have the script look in the db for

我需要让脚本在db中查找

010300000000001002

in the USERID. Then when it finds the match I need it to look for the EMPNUM value in the same row. Then take the EMPNUM value and rename the picture to that value.jpg, which in this case equals 1002. So the end product would end up like this:

在USERID中。然后当它找到匹配时,我需要它来查找同一行中的EMPNUM值。然后取EMPNUM值并将图片重命名为value.jpg,在这种情况下等于1002.所以最终产品最终会像这样:

Old Picture: 010300000000001002.jpg
New Picture: 1002.jpg

Then repeat for all of the pictures in that folder.

然后重复该文件夹中的所有图片。

Read from the DB Script:

从DB脚本中读取:

#!/usr/bin/perl -w
use strict;

use DBI;
# Replace datasource_name with the name of your data source.  AdventureWorksDW \dbo.DimEmployee
# Replace database_username and database_password
# with the SQL Server database username and password.
my $data_source = q/not giving the data source/;
my $user = q/Not giving the user/;
my $password = q/Not Giving the password /;
my $dbh = DBI->connect($data_source, $user, $password)
    or die "Can't connect to $data_source: $DBI::errstr";

# Catch and display status messages with this error handler.
sub err_handler {
   my ($sqlstate, $msg, $nativeerr) = @_;
   # Strip out all of the driver ID stuff
   $msg =~ s/^(\[[\w\s:]*\])+//;
   print $msg;
   print "===> state: $sqlstate msg: $msg nativeerr: $nativeerr\n";
   return 0;
}

$dbh->{odbc_err_handler} = \&err_handler;

$dbh->{odbc_exec_direct} = 1;

# Prepare your sql statement (perldoc DBI for much more info).
my $sth = $dbh->prepare('select userid, empnum from dbo.emp0');

# Execute the statement.
if ($sth->execute)
{
    # This will keep returning until you run out of rows.
    while (my $row = $sth->fetchrow_hashref)
    {
        print "ID = $row->{userid}, Name = $row->{empnum}\n";
    }
}

$dbh->disconnect;

Copy and rename file script:

复制并重命名文件脚本:

#!/usr/bin/perl -w
use strict;
use warnings;

my $i = 1;
my @old_names = glob "/root/pics/*.jpg";


foreach my $old_name (@old_names) {

    my $new_name = "picture$i" . ".jpg";

    rename($old_name, "/root/pics/$new_name") or die "Couldn't rename $old_name to $new_name: $!\n";

} continue { $i++ }

print "Pictures have been renamed.\n";

Edit: This is what I ended up with and it does the job.

编辑:这就是我最终完成的工作。

#!/usr/bin/perl -w
use strict;
use File::Copy;
use DBI;

my $data_source = q/db/;
my $user = q/user/;
my $password = q/password/;
my $dbh = DBI->connect($data_source, $user, $password)
    or die "Can't connect to $data_source: $DBI::errstr";

# Catch and display status messages with this error handler.
sub err_handler {
   my ($sqlstate, $msg, $nativeerr) = @_;
   # Strip out all of the driver ID stuff
   $msg =~ s/^(\[[\w\s:]*\])+//;
   print $msg;
   print "===> state: $sqlstate msg: $msg nativeerr: $nativeerr\n";
   return 0;
}
$dbh->{odbc_err_handler} = \&err_handler;
$dbh->{odbc_exec_direct} = 1;

sub move_image 
{
    my $user_id = $_[0];
    my $emp_num = $_[1];

    my $old_name = "/root/picS/${user_id}.jpg";

    my $new_name = "/root/picD/${emp_num}.jpg";

    move($old_name, $new_name) or return 0;

    return 1;
}

# Prepare your sql statement (perldoc DBI for much more info).
my $sth = $dbh->prepare('select userid, empnum from dbo.emp0');

# Execute the statement.
if ($sth->execute)
{
    # This will keep returning until you run out of rows.
    while (my $row = $sth->fetchrow_hashref)
    {
        my $user_id = $row->{userid};
        my $emp_num = $row->{empnum};

        if (move_image($user_id, $emp_num))
        {
            print "Moved image $user_id to $emp_num successfully\n";
        }
        else
        {
            print "Could not move image $user_id to $emp_num successfully\n";
        }
    }
}

$dbh->disconnect;

1 个解决方案

#1


2  

First off, I would suggest using move From File::Copy. The rename subroutine has restrictions on when it can be used. However, if you are certain that both images will always be in the same folder, then rename should be fine and may even be more efficient.

首先,我建议使用move From File :: Copy。重命名子例程对何时可以使用具有限制。但是,如果您确定两个图像将始终位于同一文件夹中,则重命名应该没问题,甚至可能更有效。

Add the following to the top of your code to be able to use File::Copy:

将以下内容添加到代码顶部以便能够使用File :: Copy:

use File::Copy;

Second, if you want to integrate the functionality here, I would make the "move" code into a subroutine.

其次,如果你想在这里集成功能,我会把“移动”代码变成子程序。

sub move_image 
{
    my $user_id = $_[0];
    my $emp_num = $_[1];

    my $old_name = "/root/pics/${user_id}.jpg";

    my $new_name = "/root/pics/picture${emp_num}.jpg";

    move($old_name, $new_name) or return 0;

    return 1;
}

Then call the subroutine:

然后调用子程序:

# This will keep returning until you run out of rows.
while (my $row = $sth->fetchrow_hashref)
{
    my $user_id = $row->{userid};
    my $emp_num = $row->{empnum};

    if (move_image($user_id, $emp_num))
    {
        print "Moved image $user_id to $emp_num successfully\n";
    }
    else
    {
        print "Could not move image $user_id to $emp_num successfully\n";
    }
}

Just add the subroutine to your original script like I showed. Don't try to use two different scripts. Subroutines are very useful.

只需像我展示的那样将子程序添加到原始脚本中。不要尝试使用两个不同的脚本。子程序非常有用。

#1


2  

First off, I would suggest using move From File::Copy. The rename subroutine has restrictions on when it can be used. However, if you are certain that both images will always be in the same folder, then rename should be fine and may even be more efficient.

首先,我建议使用move From File :: Copy。重命名子例程对何时可以使用具有限制。但是,如果您确定两个图像将始终位于同一文件夹中,则重命名应该没问题,甚至可能更有效。

Add the following to the top of your code to be able to use File::Copy:

将以下内容添加到代码顶部以便能够使用File :: Copy:

use File::Copy;

Second, if you want to integrate the functionality here, I would make the "move" code into a subroutine.

其次,如果你想在这里集成功能,我会把“移动”代码变成子程序。

sub move_image 
{
    my $user_id = $_[0];
    my $emp_num = $_[1];

    my $old_name = "/root/pics/${user_id}.jpg";

    my $new_name = "/root/pics/picture${emp_num}.jpg";

    move($old_name, $new_name) or return 0;

    return 1;
}

Then call the subroutine:

然后调用子程序:

# This will keep returning until you run out of rows.
while (my $row = $sth->fetchrow_hashref)
{
    my $user_id = $row->{userid};
    my $emp_num = $row->{empnum};

    if (move_image($user_id, $emp_num))
    {
        print "Moved image $user_id to $emp_num successfully\n";
    }
    else
    {
        print "Could not move image $user_id to $emp_num successfully\n";
    }
}

Just add the subroutine to your original script like I showed. Don't try to use two different scripts. Subroutines are very useful.

只需像我展示的那样将子程序添加到原始脚本中。不要尝试使用两个不同的脚本。子程序非常有用。