폴더의 일련 번호를 기반으로 손실된 파일을 찾는 방법

폴더의 일련 번호를 기반으로 손실된 파일을 찾는 방법

DPX 이미지가 포함된 폴더가 있는데 파일 이름이 올바른지 확인하고 싶습니다.

파일 이름의 범위는 다음과 같습니다.

프레임 0000000.dpx에서 프레임 9999999.dpx까지

폴더가 이 전체 범위를 포함하는 것은 불가능하며 위 순서에 포함된 임의의 숫자로 시작하고 끝날 수 있습니다. 시작 번호는 항상 끝 번호보다 작습니다.

어떤 도움이라도 대단히 감사하겠습니다 :-)

답변1

#!/usr/bin/perl

# open the directory in the first arg (defaults to
# .) and get a sorted list of all files ending in
# .dpx into array @files
opendir(my $dir, shift // '.');
my @files = sort grep { /^Frame .*\.dpx$/ } readdir($dir);
close($dir);

# get the numeric value of the first and last
# element of the array
my ($first) = split /\./, $files[0];
my ($last)  = split /\./, $files[-1];

#print "$first\n$last\n";

# find and print any missing filenames
foreach my $i ($first..$last) {
  my $f = sprintf("%08i.dpx",$i);
  print "File '$f' is missing\n" unless -e $f
};

예를 들어 로 저장 find-missing.pl하고 실행 가능하게 만듭니다 chmod +x find-missing.pl.

먼저, 테스트 실행을 위해 일치하는 파일 묶음을 무작위로 생성해야 합니다(이 테스트에서는 10개 이하의 파일이면 충분합니다).

$ for i in {0..9} ; do
    [ "$RANDOM" -gt 16384 ] && printf "%08i.dpx\0" "$i" ;
  done | xargs -0r touch

$ ls -l *.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000000.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000001.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000003.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000005.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000006.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000007.dpx
-rw-r--r-- 1 cas cas 0 Feb 24 13:30 00000008.dpx

Bash에서는 $RANDOM0에서 32767 사이의 임의의 숫자가 주어지므로 for루프가 파일을 생성할 확률은 약 50%입니다. 이번 실행에서는 00000002.dpx, 00000004.dpx, 00000009.dpx를 제외한 모든 항목이 생성된 것을 확인할 수 있습니다.

그런 다음 Perl 스크립트를 실행합니다.

$ ./find-missing.pl .
File '00000002.dpx' is missing
File '00000004.dpx' is missing

00000009.dpx참고: 이는 발견된 최대 번호의 파일을 초과하므로 언급되지 않습니다 . 이를 수행하려면 $last적절한 값으로 하드코딩하거나 명령줄 인수에서 가져올 수 있습니다.


.Frame@ARGVGetSelect::표준또는Getopt::긴):

#!/usr/bin/perl

# Configuration variables
my $digits = 7;
my $prefix = 'Frame ';
my $suffix = '.dpx';

# Format string for printf
my $fmt = "$prefix%0${digits}i$suffix";

# Open the directory in the first arg (defaults to
# the current dir, ".") and get a sorted list of all
# files starting with $prefix and ending in $suffix
# into array @files
opendir(my $dir, shift // '.');
my @files = sort grep { /^$prefix.*$suffix$/ } readdir($dir);
close($dir);

# Get the numeric value of the first and last
# element of the array by removing the filename
# prefix (e.g. "Frame ") and suffix (e.g. ".dpx"):
my ($first, $last);
($first = $files[0])  =~ s/^$prefix|$suffix$//g;
($last  = $files[-1]) =~ s/^$prefix|$suffix$//g;

#print "$first\n$last\n";

# find and print any missing filenames
foreach my $i ($first..$last) {
  my $f = sprintf($fmt, $i);
  print "File '$f' is missing\n" unless -e $f
};

그런데, ($first = $files[0]) =~ s/^$prefix|$suffix$//g;이것은 변수에 값을 할당하고 s///대체 작업을 통해 이를 수정하는 일반적인 Perl 관용어입니다. 이는 다음과 같습니다:

$first = $files[0];
$first =~ s/^$prefix|$suffix$//g;

총 파일 수(및 누락된 파일 수)를 인쇄하려면 # find and print any missing filenames위 버전 중 마지막 코드 블록(및 그 이후의 모든 항목)을 다음과 같이 변경합니다.

# find and print any missing filenames
my $missing = 0;
foreach my $i ($first..$last) {
  my $f = sprintf($fmt, $i);
  if (! -e $f) {
    print "File '$f' is missing\n";
    $missing++;
  };
};

printf "\nTotal Number of files: %i\n", scalar @files;
printf "Number of missing files: %i\n", $missing;

그러면 다음과 같은 출력이 생성됩니다.

$ ./find-missing2.pl 
File 'Frame 00000002.dpx' is missing
File 'Frame 00000003.dpx' is missing

Total Number of files: 7
Number of missing files: 2

답변2

무차별 대입 방법.

샘플 디렉터리 내용을 표시합니다.

/tmp/dpx-test
-rw-------.  1 root root    0 Feb 23 21:02 0
-rw-------.  1 root root    0 Feb 23 18:59 0000000
-rw-------.  1 root root    0 Feb 23 21:03 0000000.aaa
-rw-------.  1 root root    0 Feb 23 18:57 0000000.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000001.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000002.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000003.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000004.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000005.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000006.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000007.dp
-rw-------.  1 root root    0 Feb 23 18:58 0000008.dpx
-rw-------.  1 root root    0 Feb 23 18:58 0000009.dpx
-rw-------.  1 root root    0 Feb 23 21:00 000000x.dpx
-rw-------.  1 root root    0 Feb 23 20:56 0000011.dpx
-rw-------.  1 root root    0 Feb 23 18:59 0000019.dpx
-rw-------.  1 root root    0 Feb 23 21:02 0000022.dpy
drwx------.  2 root root    6 Feb 23 19:05 x
-rw-------.  1 root root    0 Feb 23 21:00 x000999.dpx
-rw-------.  1 root root    0 Feb 23 18:59 xxxx
[user1:/dpx-test:]#
[user1:/tmp/dpx-test:]#
[user1:/tmp/dpx-test:]# ls -1 [0-9][0-9][0-9][0-9][0-9][0-9][0-9].dpx | wc -l
11
[user1:/tmp/dpx-test:]#
[user1:/tmp/dpx-test:]#
[user1:/tmp/dpx-test:]# ls -1 [0-9][0-9][0-9][0-9][0-9][0-9][0-9].dpx
0000000.dpx
0000001.dpx
0000002.dpx
0000003.dpx
0000004.dpx
0000005.dpx
0000006.dpx
0000008.dpx
0000009.dpx
0000011.dpx
0000019.dpx

스크립트는 다음과 같습니다.

#!/bin/bash
D1="$1"  # Name of folder to check is passed in as argument #1
EXT='dpx'
echo "Checking for all missing ???????.dpx files."; echo
pushd "${D1}"
      # This work ASSUMES two or more '???????.dpx' files are in the given directory.
      # Gets first numbered file
      FstDPX="$(find . -type f -name '[0-9][0-9][0-9][0-9][0-9][0-9][0-9].dpx' | sort | head -1 | cut -d '/' -f2 | cut -d'.' -f1)"
      # Gets last numbered file
      LstDPX="$(find . -type f -name '[0-9][0-9][0-9][0-9][0-9][0-9][0-9].dpx' | sort | tail -1 | cut -d '/' -f2 | cut -d'.' -f1)"
      echo "First known file is:  ${FstDPX}.${EXT}"
      echo "Last  known file is:  ${LstDPX}.${EXT}"
      DPXcount="$(find . -type f -name '[0-9][0-9][0-9][0-9][0-9][0-9][0-9].'${EXT} | wc -l)"
      echo "Total number of '???????.dpx' files in $(pwd), is:  ${DPXcount}.";  echo
      if [ "${DPXcount}" -ge 3 ]; then
           # Convert value without leading zeros, and manually increment by 1(Fst) or 0(Lst).
           [ "${FstDPX}" == '0000000' ] && Fdpx="$(echo ${FstDPX} | awk '{print $0 + 1}')" \
                                        || Fdpx="$(echo ${FstDPX} | awk '{print $0 + 0}')"
           echo "FstDPX(${FstDPX}) ---- Fdpx(${Fdpx})  //First one to test for existance of//."
           Ldpx="$(echo ${LstDPX} | awk '{print $0 + 0}')"
           echo "LstDPX(${LstDPX}) ---- Ldpx(${Ldpx})."
           IDX="${Fdpx}"  # Established starting point to iterate through.
           echo "IDX(${IDX}) -- Fdpx(${Fdpx}) -- Ldpx(${Ldpx})"; echo

           echo "Now iterating through the directory and listing only those missing."; echo
           # Loop through UNTIL we've reached the end.
           until [ "${IDX}" -gt "${Ldpx}" ]; do
                   # Convert back to number with leading zeros.
                   IDXz=$(printf "%07d\n" ${IDX})
                   # Test if
                   [  ! -e "${IDXz}.dpx" ] && echo "File  '${IDXz}.dpx'  is missing"
                   let "IDX=IDX+1"
           done
      else
           echo; echo "Not enough '???????.dpx' files to process."; echo
      fi
popd

다음과 같은 출력이 생성됩니다.

Checking for all missing ???????.dpx files.

/tmp/dpx-test ~
First known file is:  0000000.dpx
Last  known file is:  0000019.dpx
Total number of '???????.dpx' files in /tmp/dpx-test, is:  11.

FstDPX(0000000) ---- Fdpx(1)  //First one to test for existance of//.
LstDPX(0000019) ---- Ldpx(19).
IDX(1) -- Fdpx(1) -- Ldpx(19)

Now iterating through the directory and listing only those missing.

File  '0000007.dpx'  is missing
File  '0000010.dpx'  is missing
File  '0000012.dpx'  is missing
File  '0000013.dpx'  is missing
File  '0000014.dpx'  is missing
File  '0000015.dpx'  is missing
File  '0000016.dpx'  is missing
File  '0000017.dpx'  is missing
File  '0000018.dpx'  is missing

관련 정보