Regex 如果在文件夹中找到图片,请写入文件

Regex 如果在文件夹中找到图片,请写入文件,regex,bash,shell,csv,Regex,Bash,Shell,Csv,我有一个csv文件,在第一列中有一个产品代码列表,由数字和大写字母组成,在第二列的可用空间中有第一列产品图片的名称 我还有一个文件夹,里面有几乎所有的图片,但图片的代码是产品代码的子字符串(编辑:前缀)。图片和产品之间的匹配是一对多的,因此多个产品共享同一图片。 例如: 我需要制作一个shell脚本,扫描csv文件中的代码列表,如果有一个图片的名称是该代码的子字符串,它会将该图片的名称写入第二列 这是我的第一个大项目,我没有数据操作方面的经验 找到图片之间的最大子字符串就是我的产品图片 由于您尚

我有一个csv文件,在第一列中有一个产品代码列表,由数字和大写字母组成,在第二列的可用空间中有第一列产品图片的名称

我还有一个文件夹,里面有几乎所有的图片,但图片的代码是产品代码的子字符串(编辑:前缀)。图片和产品之间的匹配是一对多的,因此多个产品共享同一图片。 例如:

我需要制作一个shell脚本,扫描csv文件中的代码列表,如果有一个图片的名称是该代码的子字符串,它会将该图片的名称写入第二列

这是我的第一个大项目,我没有数据操作方面的经验


找到图片之间的最大子字符串就是我的产品图片

由于您尚未指定问题所在或尝试过什么,以下是一些伪代码以帮助您入门:

foreach line in csvfile {
   code = get first column(line)
   foreach filename in folder {
      if(filename is a substring of code) { 
         //match!
         write to file ("code, filename")
         break;
      }
   }
}

由于您尚未指定您的问题是什么或您尝试了什么,以下是一些伪代码以帮助您开始:

foreach line in csvfile {
   code = get first column(line)
   foreach filename in folder {
      if(filename is a substring of code) { 
         //match!
         write to file ("code, filename")
         break;
      }
   }
}

您可以动态地组装
sed
脚本,对存在的每个图像文件进行替换

#!/bin/bash

sed -i -f <(
    find images/ -type f -name '*.jpg' | LANG=C sort -r | 
    while read imagename
    do
        basename=$(basename "$imagename" .jpg)
        echo "s#^\\($(printf "%q" "$basename")[^;]*;\\);#\\1$imagename;#"
    done) "$@"
执行
script.sh输入将导致

3234P3001;/tmp/images/3234P30.png;aa
3234P3002;/tmp/images/3234P30.png;bb

您可以动态地组装
sed
脚本,对存在的每个图像文件进行替换

#!/bin/bash

sed -i -f <(
    find images/ -type f -name '*.jpg' | LANG=C sort -r | 
    while read imagename
    do
        basename=$(basename "$imagename" .jpg)
        echo "s#^\\($(printf "%q" "$basename")[^;]*;\\);#\\1$imagename;#"
    done) "$@"
执行
script.sh输入将导致

3234P3001;/tmp/images/3234P30.png;aa
3234P3002;/tmp/images/3234P30.png;bb

这正是你想要的

假设您的产品代码存储在名为products.csv的文件中,如果您将下面的代码保存在名为“go”的文件中,请执行以下操作

chmod +x go
./go < products.csv
chmod+xgo
./go
它可能需要稍微调整一下

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use Cwd;

my $Debug=1;        # Set to 0 to turn off debug output
my $photosdir="/tmp";   # Or wherever your photos are

# Go to photos directory and load names of all JPEGs into array @photos
chdir $photosdir or die "Unable to chdir() to $photosdir\n";
my @photos=<*.jpg>;

# Debug - output photo filenames
print Dumper @photos if $Debug;

# Read product codes from our stdin
while(<>){
   chomp;
   my $product = $_ ;
   $product =~ s/;.*//;

   print "Finding photo for product: $product\n" if $Debug;

   # Run through all photo filenames and find longest match
   my $longestmatch=0;
   my $bestimage="<NONE>";

   foreach my $photo (@photos){
         # Strip extension off photo name
         $photo =~ s/\.jpg//;

         print "Assessing photo $photo\n" if $Debug;

         if($product =~ m/(^$photo)/ ){
            my $matchlength = length($&);
            if($matchlength > $longestmatch){
               print "Best match so far: $photo, ($matchlength characters)\n" if $Debug;
               $longestmatch = $matchlength;
               $bestimage = $photo . ".jpg";
            }
         }
   }
   print "$product,$bestimage\n";
}
#/usr/bin/perl
严格使用;
使用警告;
使用数据::转储程序;
使用化学武器;
我的$Debug=1;#设置为0可关闭调试输出
我的$photosdir=“/tmp”#或者无论你的照片在哪里
#转到照片目录,将所有JPEG的名称加载到数组@photos中
chdir$photosdir或die“无法将chdir()转换为$photosdir\n”;
我的@photos=;
#调试-输出照片文件名
打印转储程序@照片(如果$Debug);
#阅读我们标准DIN中的产品代码
while(){
咀嚼;
我的$product=$\;
$product=~s/;*/;
如果$Debug,则打印“查找产品照片:$product\n”;
#运行所有照片文件名并查找最长匹配项
我的$longestmatch=0;
我的$bestimage=“”;
foreach我的$photo(@photos){
#删除照片名称的扩展名
$photo=~s/\.jpg/;
如果$Debug,则打印“评估照片$photo\n”;
如果($product=~m/(^$photo)/){
my$matchlength=长度($&);
如果($matchlength>$longestmatch){
如果$Debug,则打印“迄今为止最佳匹配:$photo,($matchlength字符)\n”;
$longestmatch=$matchlength;
$bestimage=$photo.“.jpg”;
}
}
}
打印“$product$bestimage\n”;
}
事实上,使用散列可以更优雅、更快地完成。与其查看数千张照片中的每一张,直到找到最长的匹配,不如尝试查看产品的前n个字母是否在散列中,如果不尝试前n-1个字母,然后是前n-2个字母,如下所示。对于大量的产品和照片,它应该运行得更快

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use Cwd;

my $Debug=1;        # Set to 0 to turn off debug output
my $photosdir="/tmp";   # Or wherever your photos are

# Go to photos directory and load names of all JPEGs into array @filenames
chdir $photosdir or die "Unable to chdir() to $photosdir\n";
my @filenames=<*.jpg>;

# Now create hash of photonames without ".jpg" extension
my %photos;
for my $photo (@filenames){
   $photo =~ s/\.jpg//;
   # So if there was a file "xyz.jpg", $photos{"xyz"} will be defined
   $photos{$photo}=1;
}

# Debug - output photo filenames
print Dumper \%photos if $Debug;

# Read product codes from our stdin
while(<>){
   chomp;   # remove end of line
   my ($product,$field2,$field3) = split ";";

   print "Finding photo for product: $product\n" if $Debug;

   my $bestimage="<NONE>";  # Preset and overwrite if better one found

   # Keep removing last character of product till it matches a photo
   for(my $i=length($product);$i;$i--){
      my $short = substr($product,0,$i);
      print "Trying $short\n" if $Debug;
      if(defined($photos{$short})){
         $bestimage = $short . ".jpg";
         last;
      }
   }
   print "$product;$bestimage;$field3\n";
}
#/usr/bin/perl
严格使用;
使用警告;
使用数据::转储程序;
使用化学武器;
我的$Debug=1;#设置为0可关闭调试输出
我的$photosdir=“/tmp”#或者无论你的照片在哪里
#转到照片目录并将所有JPEG的名称加载到数组@filenames中
chdir$photosdir或die“无法将chdir()转换为$photosdir\n”;
我的@filename=;
#现在创建不带“.jpg”扩展名的照片名哈希
我的%照片;
对于我的$photo(@filename){
$photo=~s/\.jpg/;
#因此,如果有一个文件“xyz.jpg”,将定义$photos{“xyz”}
$photos{$photo}=1;
}
#调试-输出照片文件名
如果$Debug,打印转储程序\%照片;
#阅读我们标准DIN中的产品代码
while(){
chomp;#移除生产线末端
我的($product,$field2,$field3)=拆分“;
如果$Debug,则打印“查找产品照片:$product\n”;
my$bestimage=“”#预设并覆盖(如果找到更好的)
#继续删除产品的最后一个字符,直到它与照片匹配
对于(my$i=长度($product);$i;$i--){
my$short=substr($product,0,$i);
如果$Debug,则打印“Trying$short\n”;
if(已定义($photos{$short})){
$bestimage=$short.“.jpg”;
最后的
}
}
打印“$product;$bestimage;$field3\n”;
}

这几乎满足了您的需求

假设您的产品代码存储在名为products.csv的文件中,如果您将下面的代码保存在名为“go”的文件中,请执行以下操作

chmod +x go
./go < products.csv
chmod+xgo
./go
它可能需要稍微调整一下

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use Cwd;

my $Debug=1;        # Set to 0 to turn off debug output
my $photosdir="/tmp";   # Or wherever your photos are

# Go to photos directory and load names of all JPEGs into array @photos
chdir $photosdir or die "Unable to chdir() to $photosdir\n";
my @photos=<*.jpg>;

# Debug - output photo filenames
print Dumper @photos if $Debug;

# Read product codes from our stdin
while(<>){
   chomp;
   my $product = $_ ;
   $product =~ s/;.*//;

   print "Finding photo for product: $product\n" if $Debug;

   # Run through all photo filenames and find longest match
   my $longestmatch=0;
   my $bestimage="<NONE>";

   foreach my $photo (@photos){
         # Strip extension off photo name
         $photo =~ s/\.jpg//;

         print "Assessing photo $photo\n" if $Debug;

         if($product =~ m/(^$photo)/ ){
            my $matchlength = length($&);
            if($matchlength > $longestmatch){
               print "Best match so far: $photo, ($matchlength characters)\n" if $Debug;
               $longestmatch = $matchlength;
               $bestimage = $photo . ".jpg";
            }
         }
   }
   print "$product,$bestimage\n";
}
#/usr/bin/perl
严格使用;
使用警告;
使用数据::转储程序;
使用化学武器;
我的$Debug=1;#设置为0可关闭调试输出
我的$photosdir=“/tmp”#或者无论你的照片在哪里
#转到照片目录,将所有JPEG的名称加载到数组@photos中
chdir$photosdir或die“无法将chdir()转换为$photosdir\n”;
my@photos=;
#调试-输出照片文件名
打印转储程序@照片(如果$Debug);
#阅读我们标准DIN中的产品代码
while(){
咀嚼;
我的$product=$\;
$product=~s/;*/;
如果$Debug,则打印“查找产品照片:$product\n”;
#运行所有照片文件名并查找最长匹配项
我的$longestmatch=0;
我的$bestimage=“”;
foreach我的$photo(@photos){
#删除照片名称的扩展名
$photo=~s/\.jpg/;
如果$Debug,则打印“评估照片$photo\n”;
如果($product=~m/(^$photo)/){
my$matchlength=长度($&);
如果($matchlength>$longestmatch){
如果$Debug,则打印“迄今为止最佳匹配:$photo,($matchlength字符)\n”;
$longestmatch=$matchlength;
$bestimage=$p