AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 736674
Accepted
jim_e_jib
jim_e_jib
Asked: 2023-02-24 07:28:29 +0800 CST2023-02-24 07:28:29 +0800 CST 2023-02-24 07:28:29 +0800 CST

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

  • 772

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

文件名的范围包括:

帧 0000000.dpx 到帧 9999999.dpx

文件夹不太可能包含此完整范围,并且可能以上述序列中包含的任何数字开始和结束。开始的数字总是小于结束的数字。

任何帮助将不胜感激 :-)

windows-subsystem-for-linux
  • 2 2 个回答
  • 49 Views

2 个回答

  • Voted
  1. Joseph Wulf
    2023-02-24T10:10:10+08:002023-02-24T10:10:10+08:00

    蛮力法。

    显示示例目录内容:

    /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
    
    • 0
  2. Best Answer
    cas
    2023-02-24T10:56:08+08:002023-02-24T10:56:08+08:00
    #!/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。

    首先,我需要为测试运行随机创建一堆匹配文件(十个或更少的文件就足够了):

    $ 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 之间的随机数...因此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 . 还允许通过脚本顶部的变量进行配置 - 顺便说一句,没有理由不能从命令行获取这些(在 array 中,或使用Getopt::Std或Getopt::Long@ARGV之类的模块):

    #!/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///操作修改它。它相当于:

    $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
    
    • 0

相关问题

  • SSH linux子系统windows 10

  • Bash For循环不起作用

  • SSH进入同一网络上的两台不同机器[关闭]

  • 在 Bash 中绑定 ALT-F4 以退出的方法(Windows 上的 Ubuntu 上的 Bash)

  • 适用于 Linux 的 Windows 子系统上的 OpenZFS

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve