-1

我想在 perl 中运行这个命令

for dir in *; do
 test -d "$dir" && ( find "$dir" -name '*test' | grep -q . || echo "$dir" );
 done

我努力了 :

 system ("for dir in *; do
        test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
        done");

但不起作用。

4

4 回答 4

3

使用File::Find模块find功能的纯 Perl 实现:

#!/usr/bin/env perl

use strict;
use warnings;

use File::Find;

find \&find_directories, '.';

sub find_directories {
    if ( -d && $File::Find::name =~ /test$/ ) {
        print "$File::Find::name\n";
    }
}
于 2012-08-20T11:22:24.160 回答
1

您的报价已关闭。

"for dir in *; do
    test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
    done"

您已决定用双引号分隔您的字符串",但它们包含在您的字符串中。

要么转义其他引号

"for dir in *; do
    test -d \"\$dir\" && ( find \"\$dir\" -name '*test' | grep -q . || echo \"\$dir\" );
    done"

(容易出错,丑陋)

… 或使用另一个分隔符:Perl 为您提供了广泛的可能性。这些引用语法在内部插入变量:"…"并且qq{…}您可以在其中使用任何字符[^\s\w]作为分隔符,非插入语法是:'…'并且q{…}具有与以前相同的分隔符灵活性:

qq{for dir in *; do
    test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
    done}

qand结构可以在qq字符串中包含分隔符,如果出现是平衡的:q( a ( b ) c )有效。

第三种引用机制是here-doc

system( <<END_OF_BASH_SCRIPT );
for dir in *; do
    test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
    done
END_OF_BASH_SCRIPT

这对于包含更长的片段而不用担心分隔符很有用。字符串以预定义的标记结束,该标记必须单独出现在一行中。如果分隔符声明放在单引号 ( <<'END_OF_SCRIPT') 中,则不会插入任何变量:

system( <<'END_OF_BASH_SCRIPT' );
for dir in *; do
    test -d "$dir" && ( find "$dir" -name '*test' | grep -q . || echo "$dir" );
    done
END_OF_BASH_SCRIPT

注意q{}andqq{}语法:这是一个永远不会在混淆之外使用的功能,但可以使用字符 in\w作为分隔符。q您必须在引用运算符orqq和分隔符之间包含一个空格。这有效:q xabcx并且等于'abc'

于 2012-08-20T11:12:43.653 回答
0

不要启动脚本,而是尝试启动一个运行脚本的 bash 实例。例如

system("bash -c 'for dir bla bla bla'");
于 2012-08-20T10:56:22.910 回答
0

system()使用您的默认系统 shell,它可能不是 Bash。解决方案是使用 system() 命令显式调用 Bash

于 2012-08-20T11:01:08.847 回答