简体   繁体   English

如何在Perl中通过管道使用Unix / AIX find命令?

[英]How to use the Unix/AIX find command with a pipe in Perl?

I'm trying to use the Unix/AIX find command piped to the head command to return the first file in a directory and assign it to a variable. 我正在尝试使用通过管道传输到head命令的Unix / AIX find命令来返回目录中的第一个文件并将其分配给变量。 However, all of my attempts have resulted in the all the files that find returns being assigned to the variable without the head command being applied. 但是,我的所有尝试都导致所有未找到返回值的文件都分配给变量,而没有应用head命令。

Here's are my three attempts: 这是我的三种尝试:

Attempt 1: 
    $first_file = `/usr/bin/find $my_path -type f -name $potential_file_names | head -n1`;
Attempt 2: 
    $first_file = `/usr/bin/find $my_path -type f -name $potential_file_names '|' head -n1`;
Attempt 3:
    $first_file = `/usr/bin/find $my_path -type f -name $potential_file_names \\| head -n1`;

The $potential_file_names variable is a string with wildcard characters to return any file in the directory that's in the format "fileXXX.txt" where 'XXX' is a three digit number. $potential_file_names变量是一个带有通配符的字符串,用于返回目录中格式为“ fileXXX.txt”的任何文件,其中“ XXX”是三位数。

$potential_file_names = 'file???.txt';

The first attempt doesn't work because Perl appears to take exception to the pipe as it returns error, "sh[2]: 0403-057. 第一次尝试不起作用,因为Perl在返回错误“ sh [2]:0403-057”时似乎对管道采取了例外措施。

First attempt output: 首次尝试输出:

file001.txt
file002.txt
file003.txt
file004.txt
file005.txt

The second and third attempts also fail. 第二和第三次尝试也将失败。 The error for them is, "sh[2]: |: not found." 它们的错误是“找不到[sh [2]:|:]”。

The output for the second and third attempts is the same as the first attempt. 第二次和第三次尝试的输出与第一次尝试相同。

Is it possible to use the find command piped to head to return the first file in the directory I'm searching (in my case, "file001.txt"? 是否可以使用传递给head的find命令返回我正在搜索的目录中的第一个文件(在我的情况下为“ file001.txt”?

Update I should mention that the file names may not start with 001, so I'll need the oldest file. 更新我应该提到文件名可能不能以001开头,因此我需要最旧的文件。 The files are created sequentially, so grabbing the first file using find and piping to head -n1 works from the command line outside the script. 这些文件是按顺序创建的,因此,使用find和管道将文件头-n1捕获到第一个文件是从脚本外部的命令行进行的。 It needs to be the oldest/first file because I'll be deleting files using a loop later in the script and this needs to find the oldest/first file for each iteration. 它必须是最早/最早的文件,因为我稍后将在脚本中使用循环删除文件,并且需要为每次迭代查找最早/最先的文件。

Thanks. 谢谢。

Try something like this: 尝试这样的事情:

    open EXE, qq{/usr/bin/find $my_path -type f -name $potential_file_names | head -n1}
                    or die qq{Error running command $!};
    my $file = <EXE>;
    close(EXE);

Avoid using system and backticks when there are pure Perl equivalents; 当有纯Perl等效项时,避免使用system和反引号; your code will be more portable and you won't have to worry about nasty shell quoting issues. 您的代码将具有更高的可移植性,并且您不必担心讨厌的shell引用问题。

If you don't care about subdirectories, you can use readdir to get a list of files inside a particular directory: 如果您不关心子目录,则可以使用readdir获取特定目录中的文件列表:

#!/usr/bin/perl

use strict;
use warnings;

my $dir = 'foo';
opendir my $dh, $dir or die $!;

my @files = sort { -M "$dir/$b" <=> -M "$dir/$a" }
            grep { /^file\d{3}\.txt$/ && -f "$dir/$_" } readdir $dh;

closedir $dh;

print $files[0];

This prints the name of the file with the oldest modified date, although you could certainly use another file test instead. 尽管您当然可以使用其他文件测试来代替,但它会打印出修改日期最早的文件名。


If you also want to search inside subdirectories, you can use File::Find , which is a core module: 如果还想在子目录中搜索,可以使用File :: Find ,它是一个核心模块:

use File::Find;
use File::Spec;

my @files;
my $dir = 'foo';
find(sub { push @files, $File::Find::name if /^file\d{3}\.txt$/ and -f $_; }, $dir);

my @sorted = sort { -M $b <=> -M $a } @files;

print $sorted[0];

This prints the path to the file with the oldest modified date. 这将显示修改日期最早的文件的路径

Okay, some of the answers create a dogs breakfast for follow on coders but do point in the correct direction, with the module 'use File::Find;' 好的,有些答案会给编码员带来麻烦,但确实指向正确的方向,使用模块“ use File :: Find;”。

Sample of how I use it. 我如何使用它的样本。 find (\\&wanted, $directory); 查找(\\&wanted,$ directory); # start searching the path #开始搜索路径

sub wanted {
    my $file = $File::Find::name;
    if  (-d $file ) {
      $directoryMap{$file} = $file;
      return;
    }
    if (-z $file) {
       $zeroHash{$file} = 1;
       return;
    }
    if ($file =~                 /(AAF|MXF|NSV|Ogg|RM|SVI|SMI|WMV)$/i) {
       my $size = -s $file;
       if ($size) {
          $hashmap{$file} = $size;
          return;
       }
       else {
         $rejectMap{$file} = 1;
       return;
    }
  }
  else {
        $rejectMap{$file} = 1;
        return;
  }
 }

I use this to look for specific files with a specific extension and then I stuff them into a hash - the whole code an be found in my github in my Perl Diretory ( https://github.com/alexmac131/mediaData ). 我用它来查找具有特定扩展名的特定文件,然后将它们填充为哈希-整个代码都可以在我的Perl Diretory( https://github.com/alexmac131/mediaData )的github中找到。 you can change the wanted to something useful for you. 您可以将通缉对象更改为对您有用的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM