2016-12-05 58 views
2

我找到一個代碼function ShellFolder($source, $search1, $search2){$shellBefehl...egrep。迄今爲止工作得很好。但是現在我遇到了問題,因爲搜索到的文本文件通常包含相同的術語。現在我想鏈接兩個搜索詞,它們必須在文本文件中找到。這是我的代碼: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連接搜索模式,那麼Grep並不方便,因爲它不支持邏輯AND。它可以模擬,並與像pattern1.*pattern2一個模式,如果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 AWKawk '/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解決方案(不需要調用shell命令)。您可以逐行讀取文件,並根據您的應用邏輯測試行是否匹配使用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,如果解決了問題,請接受答案 –