Linux: So finden Sie alle Dateien mit gleichem Namen und unterschiedlichem Dateityp und verschieben sie

Linux: So finden Sie alle Dateien mit gleichem Namen und unterschiedlichem Dateityp und verschieben sie

Ich habe ein Verzeichnis mit Hunderten von Bildern, die meisten davon liegen im RAW-Format vor (Endung CR2), einige habe ich aber in JPG konvertiert, sodass ich sowohl CR2 als auch JPEG habe.

Wie bekomme ich alle Dateien, die sowohl auf JPG als auch auf CR2 enden, und verschiebe sie in ein anderes Verzeichnis?

also ls *.jpgwürde ich alle bekommen, die auf JPG enden und von dort aus müsste ich die finden, die auf CR2 enden? Wie mache ich das? Wie würde ich sie dann verschieben?

Antwort1

Ich würde find(1)für diese Aufgabe verwenden:

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

Antwort2

Eine kurze Bash-Zeile wäre:

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

Antwort3

Dazu müssen Sie ein Skript schreiben. Am besten eignen sich dafür wahrscheinlich Python oder Perl.

Hier ist ein Skript, das ich in Perl geschrieben habe und das im Wesentlichen genau das macht (JPEG- und RAW-Dateien) und das Verschieben in eine „datierte Verzeichnisstruktur“ (also JJJJ/MM-Monat/TT) automatisiert. Es verwendet die Image::ExifToolBibliothek, um das Datum des Fotos zu extrahieren und zu wissen, wo es abgelegt werden soll.

Zu Ihrer genauen Frage: Sie können sehen, dass alle JPG-Dateien gefunden werden, der Basisname ermittelt wird und dann nach einer passenden NEF-Datei gesucht wird.

#! /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";
}

Das istnichthochwertiger Code. :-) Es ist ein Hack, den ich für mich selbst geschrieben habe, aber er soll als sinnvolles Beispiel dienen.

Antwort4

Ändern Sie in diesem Skript „move2dir“ (zweimal) in den Speicherort, an dem die Dateien landen sollen, und führen Sie es dann aus dem Verzeichnis aus, in dem sich Ihre JPG- und CR2-Dateien befinden.

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

verwandte Informationen