我有一个 perl 脚本
$ cat ~/script.pl
sub main {
my ($file) = @_;
<STUFF>
}
}
foreach (@ARGV) {
main($_);
}
Run Code Online (Sandbox Code Playgroud)
我想对目录下的~/script.pl每个.txt文件执行~/foo。我可以使用命令获取.txt文件列表~/foo
$ find ~/foo -type f -name \*.txt
Run Code Online (Sandbox Code Playgroud)
我可以以某种方式使用此命令将这些文件传递给我的脚本吗?
Rob*_*rtL 11
是的,有几种方法可以使用该find命令完成此操作。我将按照我认为对理解您的情况很重要的顺序列出一些。
您的脚本似乎接受多个文件名参数,因此使用该find命令完成此操作的最有效且几乎通用的方法是:
find ~/foo -type f -name \*.txt -exec perl ~/script.pl {} +
Run Code Online (Sandbox Code Playgroud)
这将使用尽可能多的找到的文件名参数执行您的脚本。如果需要处理所有文件名,您的脚本将被多次调用。注意+行尾。
这是最原始也是最通用的方法。这对您的情况来说效率较低,因为它perl为找到的每个文件调用一次。这种用法从Unix 的早期就已经可用。请注意行尾的转义分号 ( \;)(与+上述相反)。
find ~/foo -type f -name \*.txt -exec perl ~/script.pl {} \;
Run Code Online (Sandbox Code Playgroud)在将-exec ... +语法添加到之前find,xargs发明了该命令以帮助提高处理文件名列表或其他参数时的效率。这与-exec ... +上面的示例几乎相同:
find ~/foo -type f -name \*.txt -print | xargs perl ~/script.pl
Run Code Online (Sandbox Code Playgroud)
如果您的实现支持它,您应该使用 的-print0选项find以及 的-0参数xargs。这会导致find在参数字符串之间打印空字符,并防止xargs在除空字符之外的任何内容上拆分参数。xargs如果您的文件名包含空格或其他一些特殊字符,这有助于防止错误地拆分参数。
使用-exec ... +语法通常是一个更好的主意,因为find然后将文件名直接放入脚本的参数列表中,从而消除了一个过程,并避免了通过管道传输到xargs. 但是,xargs如果您需要对过程进行更多控制,则可能具有优势。请参阅xargs手册页。
您还可以查看find2perl使用相同参数的命令find并打印一个perl程序来执行相同的操作。然后,您可以将生成的perl代码合并到您的脚本中。在下面生成的脚本中,您将修改最后一行的下一行以调用您的函数而不是print.
$ find2perl foo -type f -name \*.txt # /*
#[some preamble code removed for brevity]
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, 'foo');
exit;
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
-f _ &&
/^.*\.txt\z/s
&& print("$name\n");
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
2450 次 |
| 最近记录: |