首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从文件夹中的顺序编号中查找丢失的文件

如何从文件夹中的顺序编号中查找丢失的文件
EN

Unix & Linux用户
提问于 2023-02-23 23:28:29
回答 2查看 131关注 0票数 0

我有包含DPX图像的文件夹,我希望能够检查文件命名是否是顺序的。

文件名的范围可以是:

帧0000000.dpx到帧9999999.dpx

文件夹不可能包含此完整范围,并且可能以上述序列中包含的任意数字开始和结束。开始的时间总是比结束的时候少。

如有任何帮助,将不胜感激:)

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2023-02-24 02:56:08

代码语言:javascript
复制
#!/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个或更少的文件足以满足这个测试):

代码语言:javascript
复制
$ 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中,$RANDOM给出了0到32767...so之间的随机数-- for循环创建任何文件的几率大约为50%。在此运行中,您可以看到除了00000002.dpx、00000004.dpx和00000009.dpx之外,其他所有都是创建的。

然后运行perl脚本:

代码语言:javascript
复制
$ ./find-missing.pl .
File '00000002.dpx' is missing
File '00000004.dpx' is missing

注意:它没有提到00000009.dpx,因为这超出了找到的最高编号文件。如果您希望它这样做,那么要么将$last硬编码到合适的值,要么从命令行参数中提取它。

第二个版本,用于以Frame开头的文件名。还允许通过脚本顶部的变量进行配置- BTW,没有理由不能从命令行(在数组@ARGV中,或者使用像Getopt::StdGetopt::Long这样的模块)获取这些变量:

代码语言:javascript
复制
#!/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;是一种常用的perl成语,用于为变量赋值并使用替换s///操作修改它。相当于:

代码语言:javascript
复制
$first = $files[0];
$first =~ s/^$prefix|$suffix$//g;

若要打印文件总数(以及丢失文件的数量),请将上述任何版本中的最后一个代码块(从# find and print any missing filenames开始)更改为:

代码语言:javascript
复制
# 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;

这将产生这样的产出:

代码语言:javascript
复制
$ ./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
票数 0
EN

Unix & Linux用户

发布于 2023-02-24 02:10:10

蛮力法

显示示例目录内容:

代码语言:javascript
复制
/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

这是一个脚本:

代码语言:javascript
复制
#!/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

它产生这个输出:

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/736674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档