Linux: 同じ名前でファイルタイプが異なるすべてのファイルを検索して移動する方法

Linux: 同じ名前でファイルタイプが異なるすべてのファイルを検索して移動する方法

何百もの画像が入ったディレクトリがあり、そのほとんどは RAW 形式 (CR2 で終わる) ですが、一部は jpg に変換したので、CR2 と JPEG の両方があります。

jpg と cr2 の両方で終わるすべてのファイルを取得して、別のディレクトリに移動するにはどうすればよいですか。

jpg で終わるものをすべて取得しls *.jpg、そこから cr2 で終わるものを探す必要がありますか? どうすればいいですか? その後、それらをどのように移動しますか?

答え1

find(1)このタスクには以下を使用します:

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

答え2

簡単な bash 行は次のようになります。

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

答え3

これを行うにはスクリプトを作成する必要がありますが、おそらく Python または Perl が最適です。

これは私が Perl で書いたスクリプトで、基本的にこれ (jpeg および raw ファイル) を実行し、それらを「日付付きディレクトリ構造」(つまり、YYYY/MM-月/DD) に自動的に移動します。Image::ExifToolライブラリを使用して写真の日付を抽出し、写真を配置する場所を判断します。

正確な質問については、すべての .jpg ファイルを検索し、ベース名を解析してから、一致する .nef ファイルをチェックしていることがわかります。

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

これはない高品質なコードです。:-) これは私が自分用に書いたハックですが、適切な例として役立つはずです。

答え4

このスクリプト内の「move2dir」を、ファイルの保存先となる場所に (2 回) 変更し、jpg ファイルと cr2 ファイルがあるディレクトリから実行します。

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

関連情報