2016-12-05 7 views
2

function ShellFolder($source, $search1, $search2){$shellBefehl...egrepというコードが見つかりました。これまでのところかなりうまく動作します。しかし、今では問題があります。検索されたテキストファイルには同じ用語が含まれることが多いからです。今では、2つの検索語を互いにリンクして、テキストファイルで検索する必要があります。これは私のコードです:php関数ShellFolderとANDリンク

<?php 
function ShellFolder($source, $search1, $search2){ 
    $shellBefehl = "egrep -o -w -l -a --directories=recurse '$search1' '$search2' $source"; 
    exec($shellBefehl, $var); 
    return $var; 
} 

//$source = 'grep.txt'; 
$source = './ordner/daten'; 
$search1 = $this->item->title; 
$search2 = $extraField->value; 
$var = ShellFolder($source, $search1, $search2); 

$myResult = print_r($var, true); 

$text = $myResult; 
$text_ohne = substr($myResult, 19); 
$insgesamt = $text_ohne; 
$insgesamt_neu=substr($insgesamt,0,-3); 
echo ($search1); 
echo ($search2); 
$lines = file("$insgesamt_neu"); 

foreach($lines as $line) { 
    echo($line); 
} 

助けてもらえますか?

答えて

1

Grepの

これは、例えば、-Eオプションを介しGrepのに複数のパターンを通過することが可能です。しかし、Grepはのいずれかのパターンをで検索します。

検索パターンを論理ANDで結合する場合は、論理ANDをサポートしていないため、Grepは便利ではありません。 pattern1pattern2に先行することになっている場合は、AND pattern1.*pattern2ようなパターンでシミュレートすることが可能である:

$patterns = ['pattern1', 'pattern2']; 
$dir = escapeshellarg($dir); 
$pattern = escapeshellarg(implode('.*', $patterns)); 
$command = "egrep -o -w -l -a -r $pattern $dir"; 
exec($command, $output, $exit_status); 

それともpattern1.*pattern2|pattern2.*pattern1任意の順序のために。しかし、一般的な場合、パターンは最適ではない。言い換えると、Grepは一般的なケースには適していないため、別のツールを使用する必要があります。

AWK

portable way to search for multiple patterns using AWKがあります:awk '/pattern1/ && /pattern2/ && ... ' file。しかし、AWKは、単一のファイルを受け取り、手動でディレクトリを反復処理し、各ファイルにコマンドを適用する必要があります:

<?php 
/** 
* Searches for lines matching all regexp patterns. 
* 
* @param string $dir Path to directory with text files 
* @param array $patterns AWK patterns without regexp markers ('/') 
* @return array Files matching all patterns 
* @throws InvalidArgumentException 
*/ 
function grepDir($dir, array $patterns, callable $callback) { 
    if (!$patterns) { 
    throw new InvalidArgumentException("Invalid patterns"); 
    } 

    // Build command as awk '/pattern1/ && /pattern2/ && ... path-to-file' 
    $awk_script = '/' . implode('/ && /', $patterns) . '/'; 
    $awk_script = escapeshellarg($awk_script); 
    $command_format = "awk $awk_script %s"; 

    try { 
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); 

    $it->rewind(); 
    while ($it->valid()) { 
     if (!$it->isDot()) { 
     $file_path = $it->key(); 
     $command = sprintf($command_format, $file_path); 
     $output = null; 
     exec($command, $output, $exit_status); 

     if ($exit_status) { 
      trigger_error("Command failed: $command"); 
      continue; 
     } 

     if ($output) { 
      $callback($file_path, $output); 
     } 
     } 

     $it->next(); 
    } 
    } catch (Exception $e) { 
    trigger_error($e->getMessage()); 
    return false; 
    } 
    return true; 
} 

$dir = '.'; 
$patterns = [ '456', '123' ]; 

grepDir($dir, $patterns, function ($file_path, array $output) { 
    printf("File: %s\nLines:\n%s\n--------\n", 
    $file_path, implode(PHP_EOL, $output)); 
}); 

サンプル出力

File: ./file1 
Lines: 
123 sdfsf 456 
456 & 123 
-------- 
File: ./test/file1 
Lines: 
456123 

PHP

例シェルコマンドを呼び出すことなく、簡単に純粋なPHPソリューションに変換することができます。ラインは、アプリケーションのロジックに従ってpreg_match()を使用したパターンと一致した場合には、ラインと試験によるファイルの行を読むことができます:

$patterns = ['456', '123']; 

$file = 'file1'; // Replace with $it->key() in the example above 
if (! $fp = fopen('file1', 'r')) { 
    throw new RuntimeException("Failed to open file $file"); 
} 

while ($line = fgets($fp)) { 
    $matches = true; 
    foreach ($patterns as $pattern) { 
    // You might want to quote the pattern, if it isn't supposed to be 
    // interpreted as a regular expression: 
    // $pattern = preg_quote($pattern, '/'); 
    if (!preg_match("/{$pattern}/", $line)) { 
     $matches = false; 
     break; 
    } 
    } 

    if ($matches) { 
    echo "Line $line matches all patterns\n"; 
    } 
} 

fclose($fp); 
+0

多くの感謝を。私はうまくいきます。 –

+0

@UweJansen、問題が解決する場合は、答えを受け入れてください –