使用 perl 脚本在目录中查找文件
finding a file in directory using perl script
我正在尝试开发一个 perl 脚本,它可以在用户的所有目录中查找特定文件名,而无需用户指定文件的完整路径名。
例如,假设感兴趣的文件是 data.list
。它位于 /home/path/directory/project/userabc/data.list
。在命令行中,通常用户必须指定文件的路径名才能访问它,如下所示:
cd /home/path/directory/project/userabc/data.list
相反,我希望用户只需在命令行中输入 script.pl ABC
,然后 Perl 脚本将自动 运行 并检索 data.list.
中的信息我的情况是计算行数并使用 curl 上传。剩下的就完成了,就是自动定位文件的部分
即使在 Perl 中非常可行,这在 Bash 中看起来更合适:
#!/bin/bash
filename=$(find ~ -name "" )
wc -l "$filename"
curl .......
主要问题当然是如果您有多个文件 data1
,例如 /home/user/dir1/data1
和 /home/user/dir2/data1
。您将需要一种方法来处理它。而你如何处理它取决于你的具体情况。
在 Perl 中会复杂得多:
#! /usr/bin/perl -w
eval 'exec /usr/bin/perl -S [=11=] ${1+"$@"}'
if 0; #$running_under_some_shell
use strict;
# Import the module File::Find, which will do all the real work
use File::Find ();
# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.
# for the convenience of &wanted calls, including -eval statements:
# Here, we "import" specific variables from the File::Find module
# The purpose is to be able to just type '$name' instead of the
# complete '$File::Find::name'.
use vars qw/*name *dir *prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
# We declare the sub here; the content of the sub will be created later.
sub wanted;
# This is a simple way to get the first argument. There is no
# checking on validity.
our $filename=$ARGV[0];
# Traverse desired filesystem. /home is the top-directory where we
# start our seach. The sub wanted will be executed for every file
# we find
File::Find::find({wanted => \&wanted}, '/home');
exit;
sub wanted {
# Check if the file is our desired filename
if ( /^$filename\z/) {
# Open the file, read it and count its lines
my $lines=0;
open(my $F,'<',$name) or die "Cannot open $name";
while (<$F>){ $lines++; }
print("$name: $lines\n");
# Your curl command here
}
}
您需要查看参数解析,为此我只是使用了 $ARGV[0]
,我不知道您的 curl 是什么样子。
一种更简单(但不推荐)的方法是滥用 Perl 作为一种 shell:
#!/usr/bin/perl
#
my $fn=`find /home -name '$ARGV[0]'`;
chomp $fn;
my $wc=`wc -l '$fn'`;
print "$wc\n";
system ("your curl command");
以下代码片段演示了实现预期结果的多种方法之一。
该代码采用一个参数,即要在文件 data.list
内的所有子目录中查找的单词。并在终端中打印出找到的文件列表。
该代码使用子例程 lookup($dir,$filename,$search)
,一旦遇到子目录就会递归调用自身。
搜索从当前工作目录开始(问题是没有指定目录作为起点)。
use strict;
use warnings;
use feature 'say';
my $search = shift || die "Specify what look for";
my $fname = 'data.list';
my $found = lookup('.',$fname,$search);
if( @$found ) {
say for @$found;
} else {
say 'Not found';
}
exit 0;
sub lookup {
my $dir = shift;
my $fname = shift;
my $search = shift;
my $files;
my @items = glob("$dir/*");
for my $item (@items) {
if( -f $item && $item =~ /\b$fname\b/ ) {
my $found;
open my $fh, '<', $item or die $!;
while( my $line = <$fh> ) {
$found = 1 if $line =~ /\b$search\b/;
if( $found ) {
push @{$files}, $item;
last;
}
}
close $fh;
}
if( -d $item ) {
my $ret = lookup($item,$fname,$search);
push @{$files}, $_ for @$ret;
}
}
return $files;
}
运行 作为 script.pl search_word
输出样本
./capacitor/data.list
./examples/data.list
./examples/test/data.list
我正在尝试开发一个 perl 脚本,它可以在用户的所有目录中查找特定文件名,而无需用户指定文件的完整路径名。
例如,假设感兴趣的文件是 data.list
。它位于 /home/path/directory/project/userabc/data.list
。在命令行中,通常用户必须指定文件的路径名才能访问它,如下所示:
cd /home/path/directory/project/userabc/data.list
相反,我希望用户只需在命令行中输入 script.pl ABC
,然后 Perl 脚本将自动 运行 并检索 data.list.
中的信息我的情况是计算行数并使用 curl 上传。剩下的就完成了,就是自动定位文件的部分
即使在 Perl 中非常可行,这在 Bash 中看起来更合适:
#!/bin/bash
filename=$(find ~ -name "" )
wc -l "$filename"
curl .......
主要问题当然是如果您有多个文件 data1
,例如 /home/user/dir1/data1
和 /home/user/dir2/data1
。您将需要一种方法来处理它。而你如何处理它取决于你的具体情况。
在 Perl 中会复杂得多:
#! /usr/bin/perl -w
eval 'exec /usr/bin/perl -S [=11=] ${1+"$@"}'
if 0; #$running_under_some_shell
use strict;
# Import the module File::Find, which will do all the real work
use File::Find ();
# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.
# for the convenience of &wanted calls, including -eval statements:
# Here, we "import" specific variables from the File::Find module
# The purpose is to be able to just type '$name' instead of the
# complete '$File::Find::name'.
use vars qw/*name *dir *prune/;
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
# We declare the sub here; the content of the sub will be created later.
sub wanted;
# This is a simple way to get the first argument. There is no
# checking on validity.
our $filename=$ARGV[0];
# Traverse desired filesystem. /home is the top-directory where we
# start our seach. The sub wanted will be executed for every file
# we find
File::Find::find({wanted => \&wanted}, '/home');
exit;
sub wanted {
# Check if the file is our desired filename
if ( /^$filename\z/) {
# Open the file, read it and count its lines
my $lines=0;
open(my $F,'<',$name) or die "Cannot open $name";
while (<$F>){ $lines++; }
print("$name: $lines\n");
# Your curl command here
}
}
您需要查看参数解析,为此我只是使用了 $ARGV[0]
,我不知道您的 curl 是什么样子。
一种更简单(但不推荐)的方法是滥用 Perl 作为一种 shell:
#!/usr/bin/perl
#
my $fn=`find /home -name '$ARGV[0]'`;
chomp $fn;
my $wc=`wc -l '$fn'`;
print "$wc\n";
system ("your curl command");
以下代码片段演示了实现预期结果的多种方法之一。
该代码采用一个参数,即要在文件 data.list
内的所有子目录中查找的单词。并在终端中打印出找到的文件列表。
该代码使用子例程 lookup($dir,$filename,$search)
,一旦遇到子目录就会递归调用自身。
搜索从当前工作目录开始(问题是没有指定目录作为起点)。
use strict;
use warnings;
use feature 'say';
my $search = shift || die "Specify what look for";
my $fname = 'data.list';
my $found = lookup('.',$fname,$search);
if( @$found ) {
say for @$found;
} else {
say 'Not found';
}
exit 0;
sub lookup {
my $dir = shift;
my $fname = shift;
my $search = shift;
my $files;
my @items = glob("$dir/*");
for my $item (@items) {
if( -f $item && $item =~ /\b$fname\b/ ) {
my $found;
open my $fh, '<', $item or die $!;
while( my $line = <$fh> ) {
$found = 1 if $line =~ /\b$search\b/;
if( $found ) {
push @{$files}, $item;
last;
}
}
close $fh;
}
if( -d $item ) {
my $ret = lookup($item,$fname,$search);
push @{$files}, $_ for @$ret;
}
}
return $files;
}
运行 作为 script.pl search_word
输出样本
./capacitor/data.list
./examples/data.list
./examples/test/data.list