Linux: Como encontrar todos os arquivos com o mesmo nome, tipo de arquivo diferente e movê-los

Linux: Como encontrar todos os arquivos com o mesmo nome, tipo de arquivo diferente e movê-los

Eu tenho um diretório com centenas de imagens, algumas delas em formato raw (terminando em CR2), mas para algumas eu as converti para jpg, então tenho CR2 e JPEG.

Como faço para obter todos os arquivos que terminam em jpg e cr2 e movê-los para outro diretório.

então ls *.jpgme daria todos aqueles que terminam em jpg e a partir daí preciso encontrar aqueles que terminam em cr2? como faço isso? como eu os moveria?

Responder1

Eu usaria find(1)para esta tarefa:

find . -name '*.jpg' -exec /bin/sh -c 'A=`basename {} .jpg`.cr2 ; test -f $A && mv {} $A /other/dir' \;

Responder2

Uma linha rápida seria:

for FILE in `ls *.jpg`; do BF=`basename $FILE .jpg`; 
   if test -e $BF.cr2 ; then mv $BF.jpg $BF.cr2 destdir/; fi; done

Responder3

Você precisará escrever um script para fazer isso, sendo Python ou Perl provavelmente sua melhor aposta.

Aqui está um script que escrevi em Perl que faz basicamente isso (arquivos jpeg e raw) e automatiza a movimentação deles para uma "estrutura de diretório datada" (ou seja, AAAA/MM-mês/DD). Ele usa a Image::ExifToolbiblioteca para extrair a data da foto para saber onde colocá-la.

Para sua pergunta exata, você pode ver que ele encontra todos os arquivos .jpg, calcula o nome de base e verifica se há um arquivo .nef correspondente.

#! /usr/bin/perl

$dryrun = 0;
$encode = 1;

use Image::ExifTool;
use Dumpvalue;
my $Dumper = new Dumpvalue();

@Months = qw(00 01-January 02-February 03-March 04-April 05-May 06-June 07-July 08-August 09-September 10-October 11-November 12-December);

$startdir = shift @ARGV;
die "error: no start directory specified\n" unless ($startdir ne "");
foreach $file (split(/\n/,`find "$startdir" -name "*.[Jj][Pp][Gg]" -print | sed -e 's,^\./,,'`)) {
  next if ($file =~ m,(^|/).xvpics/,);

  print STDERR "$file => ";
  my $exif = new Image::ExifTool;
  $info = $exif->ImageInfo($file);
  if (ref($info) != "HASH") {
    print STDERR "error: could not read exif data from '$file' ($@)\n";
    next;
  }

  ($filename) = ($file =~ m,([^/]+)$,);
  #     $Dumper->dumpValue($info);
  #     next;
  #     exit(1);

  $date = $info->{"CreateDate"};
  #print STDERR $date," => ";

  unless (($y,$m,$d,$h,$n,$s) = ($date =~ m/^(\d\d\d\d)\D(\d\d)\D(\d\d)\D+(\d\d)\D(\d\d)\D(\d\d)($|\D)/)) {
    $date = $info->{"FileModifyDate"};
    unless (($y,$m,$d,$h,$n,$s) = ($date =~ m/^(\d\d\d\d)\D(\d\d)\D(\d\d)\D+(\d\d)\D(\d\d)\D(\d\d)($|\D)/)) {
      print STDERR "$file: no date for '$file' (skipped)\n";
      next;
    }
  }

  next if ($file eq "$outdir/$filename");
  system("mkdir","-p",$outdir) unless (-d $outdir || $dryrun);

  print STDERR "$outdir/".$filename;
  rename($file,"$outdir/".$filename) unless $dryrun;

  $jpgfile  = $filename;
  $file     =~ s/\....$/\.nef/;
  $filename =~ s/\....$/\.nef/;
  if (-f $file) {
    print STDERR " ($outdir/$filename)";
    rename($file,"$outdir/".$filename) unless $dryrun;
    chmod(0644, "$outdir/".$jpgfile) unless $dryrun;
  }

  print STDERR "\n";
}

Isso énãocódigo de alta qualidade. :-) É um hack que escrevi para mim mesmo, mas deveria servir como um exemplo razoável.

Responder4

Altere 'move2dir' neste script (duas vezes) para onde os arquivos devem estar e, em seguida, execute-o a partir do diretório em que seus arquivos jpg e cr2 estão.

for file in `ls *jpg`
do
  if [ -e ${file/%jpg/cr2} ] 
  then
    cr2file=${file/%jpg/cr2}
    mv $file move2dir/
    mv $cr2file move2dir/
    echo moved $file and $cr2file
  fi
done

informação relacionada