Linux: 이름이 같고 파일 형식이 다른 모든 파일을 찾아서 이동하는 방법

Linux: 이름이 같고 파일 형식이 다른 모든 파일을 찾아서 이동하는 방법

수백 개의 이미지가 포함된 디렉토리가 있는데 그 중 일부는 원시 형식(CR2로 끝남)이지만 일부는 jpg로 변환했기 때문에 CR2와 JPEG가 모두 있습니다.

jpg와 cr2로 끝나는 모든 파일을 어떻게 가져와서 다른 디렉토리로 옮길 수 있나요?

그러면 ls *.jpgjpg로 끝나는 모든 항목을 제공하고 거기에서 cr2로 끝나는 항목을 찾아야 합니까? 어떻게 해야 합니까? 그러면 어떻게 옮길 수 있나요?

답변1

find(1)이 작업에 다음을 사용합니다 .

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

답변2

빠른 배쉬 라인은 다음과 같습니다:

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을 사용하여 이 작업을 수행하는 것이 가장 좋은 방법일 수 있는 스크립트를 작성해야 합니다.

다음은 기본적으로 이를 수행하고(jpeg 및 원시 파일) 이를 "날짜가 지정된 디렉토리 구조"(예: YYYY/MM-월/DD)로 자동 이동하는 Perl로 작성한 스크립트입니다. 라이브러리를 사용하여 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'을 파일이 끝날 위치로 두 번 변경한 다음 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

관련 정보