如何在Linux系统中查找多个文件

如何在Linux系统中查找多个文件

我的系统中有大量文件,每个文件都有一个对应的文件名。例如,

test.pdf有一个test-project.zip test2.pdf有一个test2-project.zip

test.pdftest2.pdf是原始文件,而test-project.ziptest2-project.zip由我的脚本生成。

我需要查明我的所有原始文件是否'filename'-project.zip与原始文件有对应关系。

我可以用

find /project/ -name "*.pdf" | wc -l
find /project/ -name "*-project.zip" | wc -l

查明数字是否匹配,但我需要知道哪个文件没有对应的文件。

有人能帮我吗?非常感谢!

答案1

快速脚本,根据您的需要进行调整:

#!/usr/bin/env bash

find /project/ -name '*.pdf' -print0 | while read -d $'\0' i; do
  if [ ! -e "${i/%.pdf/-project.zip}" ]; then
    echo "${i/%.pdf/-project.zip} doesn't exist!"
  fi
done

exit 0

-d $'\0'将 的分隔符设置为readnullbyte,而-print0相当于find,因此这应该可以防止名称中带有空格和换行符的文件(在这种情况下显然无关紧要,但一般情况下很有用)。将变量末尾的${i/%.pdf/-project.zip}替换为。除此之外,这些都是标准的 shell 脚本内容。.pdf$i-project.zip

如果你想进一步缩短它,你也可以使用

[ -e "${i/%.pdf/-project.zip}" ] || echo "${i/%.pdf/-project.zip} doesn't exist!"

...而不是语句if。我认为,if如果您使用多条短行,则更容易使用(您可以使用函数来解决这个问题,但此时与使用相比,您不会节省任何空间if)。

假设您有 bash 4+(您可能有;您可以使用 检查bash --version),您可以使用 globstar 选项代替find

#!/usr/bin/env bash

shopt -s globstar
for f in /project/**/*.pdf; do
  if [ ! -e "${f/%.pdf/-project.zip}" ]; then
    echo "${f/%.pdf/-project.zip} doesn't exist!"
  fi
done

exit 0

它的优点是纯 bash,所以速度应该更快(但只有在至少数百个文件时才会明显更快)。

答案2

有两种方法可以实现这一点。一种方法是使用 Bash 单行命令,它会为每个匹配的文件生成至少一个(可能两个)进程:

[me@box] $ for file in `find -name '*.pdf' -exec perl -le'$f=shift(); $f =~ s@\.pdf$@@; print $f' {} \;`; do (TESTFILE="$file-project.zip"; if [ ! -f $TESTFILE ]; then echo "missing $TESTFILE"; fi); done

因为这足以让任何人大吃一惊,这里有一个 Perl 脚本可以完成同样的工作,而且比任何 Bash 脚本都要合理得多:

#!/usr/bin/env perl
use strict;

my $path = shift() || die "$0 requires a path argument\n";
my @files = `find "$path" -name '*.pdf'`;

foreach my $file (@files) {
  chomp $file;
  my $zip = $file;
  $zip =~ s@\[email protected]@;
  next if -f $zip;
  print "missing $zip\n";
};

将其复制到例如“find-missing.pl”中,然后调用find-missing.pl /project/

相关内容