Page 1 of 1

Fulltext-Search

PostPosted: Fri Mar 15, 2024 9:02 am
by Otto
Hello friends,

I'm working on a full-text search module. I'm using findstr.

findstr is a command-line tool in Windows Command Prompt (cmd) that allows you to search for text patterns within files.

I'm building a batch file with all the parameters and then call it with waitrun(). I redirect the response from findstr to a file and then examine the hits.

Actually, the program only needs the search string and the path for now.

I'm using a DIALOG here. It's an experiment with using a HASH instead of variables, but you can easily build your own input DIALOG.
Using a HASHis a bit unusual at the beginning.

I need this search for my DMS system. I will gradually expand the query filters.

Best regards,
Otto


Code: Select all  Expand view


#include "fivewin.ch"

static h := {=>}
static oTimer


REQUEST DBFCDX
REQUEST DBFFPT

function main

   DEFINE FONT h["oFont"]  ;
          NAME "Segoe UI" ;
          SIZE 0, -32

    DEFINE FONT h['oFont2'] ;
          NAME "Segoe UI" ;
          SIZE 0, -16

    // Dialog-Block
   h['nWidthDlg'] := GetSysMetrics( 0 ) / 3
   h['nHeightDlg'] := GetSysMetrics( 1 ) / 3
   h['nLine'] := 0
   h['nRowSpace'] := 60
   h['nRowOffset'] := 20
   h['cUeberschrift'] := "Volltextsuche"
   h['nSpalte'] := 1

    DEFINE DIALOG h['oDlg'] ;
           TITLE h["cUeberschrift"] ;
            SIZE h['nWidthDlg'], h['nHeightDlg'];
            FONT h["oFont"] ;
        TRUEPIXEL
//----------------------------------------------------------------------------//
    h["cUeberschrift"] := "Suchen nach  "
    h['nWidth'] := 100
    h['nheight'] := GetTextHeight( h['oDlg']:hWnd, h["cUeberschrift"], h["oFont2"] ) * 1.4
    h['text'] := CLR_BLUE
    h['nLine'] := 0.5
    h['nColOffset'] := 20
     
    @ h["nRowOffset"] + h['nRowSpace'] * h["nLine"] ,h["nColOffset"] ;
             SAY h["cUeberschrift"] ;
              OF h['oDlg'] ;
           PIXEL ;
            FONT h["oFont2"] ;
           RIGHT ;
           COLOR CLR_WHITE, h["text"] ;
            SIZE h["nWidth"], h["nheight"]

     h["oGet"] := "Get1"
     h["nColOffset"] := 250
     h['searchstring'] := space(100)
     h["nWidth"] := 250
     h['nheight'] := GetTextHeight( h['oDlg']:hWnd, h["cUeberschrift"], h["oFont"] ) * 3
   
     @ h["nRowOffset"] + h['nRowSpace'] * h["nLine"] ,h["nColOffset"] ;
             GET h["oGet"] ;
             VAR h['searchstring'] ;
              OF h['oDlg'] ;
           PIXEL ;
            SIZE h["nWidth"],  h['nheight'] 
   
       *----------------------------------------------------------
   
        h['nLine'] += 1
        h["cUeberschrift"]  := "Searchdirectory "
        h['nWidth'] := 100
        h['nheight'] := GetTextHeight( h['oDlg']:hWnd, h["cUeberschrift"], h["oFont2"] ) * 1.4
        h['text'] := CLR_GREEN
        h['nColOffset']         := 20
       *----------------------------------------------------------     
       create_say()
       
        h["oGet"] := "oGet2"
        h["nColOffset"] := 250
        h['seachpath'] := "c:\fwh2023\samples" + space(300)
        h["nWidth"] := 400
        h['nheight'] := GetTextHeight( h['oDlg']:hWnd, h["cUeberschrift"], h["oFont"] ) * 3
   
        create_get( h['seachpath'] )

      h['lOK'] := .f.
     
       *----------------------------------------------------------
        h['btncaption'] := ""
   
        h['leftoffset'] :=   10
        h['bottomoffset'] :=   h['nHeightDlg'] - ( 38 )  - 10
        h['obtn'] := NIL
   
        h['nPixPerChar'] := 0
        h['nheight'] := ( 38 )
        h['abstand'] := 5
   
        h['oFont'] := TFont():New( 'Wingdings 3', 0, -32, .f., .f., 0, 0, 400, .f., .f., .f., 2,3, 2, 1,, 18 )
        h['text'] := CLR_BLUE
        h['bg'] := RGB( 252, 185, 19 )
        *----------------------------------------------------------
     
        h['btncaption'] := CHR(2001)
        h['text'] := CLR_BLACK
        h['bg'] := RGB( 210, 210, 210 )
   
    @ h['bottomoffset'], h['leftoffset']  ;
        BTNBMP h['obtn'] ;
        PROMPT h['btncaption']  ;
        LEFT FLAT;
        PIXEL ;
        FONT h['oFont'] ;
        SIZE h['nPixPerChar'], h['nheight'] ;
        COLOR h['text'], h['bg'];
        OF h['oDlg'] ;
    ACTION ( h['oDlg']:End() ) ;
    CANCEL
   
   
    *----------------------------------------------------------
    h['btncaption'] := "Suchen"
    h['file'] := ".\bmpMetro\BTN32_VOLLTEXTSUCHE.bmp"
     h['text'] := CLR_WHITE
    h['bg'] := RGB( 44, 84, 75 )
 
    h['leftoffset'] := If( h['obtn'] == nil, 25, h['leftoffset'] + h['abstand'] + h['obtn']:nWidth )
    h['nPixPerChar'] := GetTextWidth( h['oDlg']:hWnd, h['btncaption'], h['oFont2'] ) + 160  
   
    @ h['bottomoffset'], h['leftoffset']  ;
        BTNBMP h['obtn'];
        PROMPT h['btncaption'] ;
        FILE h['file'];
        LEFT FLAT;
        PIXEL;
        FONT h['oFont2'] ;
        SIZE h['nPixPerChar'], h['nheight'];
        COLOR h['text'], h['bg'];
        OF h['oDlg'] ;
        ACTION (  h['lOK'] := .t., volltxtSearch()  )
      *----------------------------------------------------------
   ACTIVATE DIALOG h['oDlg'] CENTERED

return
//----------------------------------------------------------------------------//

INIT PROCEDURE PrgInit
   
    SET CENTURY ON
    SET EPOCH TO YEAR(DATE())-98
    SET DELETED ON
    SET EXCLUSIVE OFF
   
    REQUEST HB_Lang_DE
    HB_LangSelect("DE")
    SET DATE TO GERMAN
    rddsetdefault( "DBFCDX" )
   
    EXTERN DESCEND
   
RETURN
//----------------------------------------------------------------------------//

function create_say()
    @ h["nRowOffset"] + h["nRowSpace"] * h["nLine"],h["nColOffset"] ;
         SAY h["cUeberschrift"] ;
          OF h["oDlg"] ;
       PIXEL ;
        FONT h["oFont2"] ;
       RIGHT ;
       COLOR CLR_WHITE, h["text"] ;
        SIZE h["nWidth"], h["nheight"]

return nil
//----------------------------------------------------------------------------//

function create_get( )
    @ h["nRowOffset"] + h["nRowSpace"] * h["nLine"],h["nColOffset"] ;
         GET h["oGet"] ;
         VAR h["seachpath"] ;
          OF h["oDlg"] ;
       PIXEL ;
        SIZE h["nWidth"], h["nheight"]
   
return nil        
//----------------------------------------------------------------------------//

function volltxtSearch()
    local cText := ""

    ferase( ALLTRIM( h['seachpath'] ) + "\results.txt" )
    cText += "cd " + ALLTRIM( h['seachpath'] ) + CRLF
    cText += "REM Erzeugen einer Lock-Datei" + CRLF
    cText += "echo Lock > results.lock" + CRLF
    cText += "REM Ausführen der Suche und Umleiten der Ausgabe in eine Datei" + CRLF
    cText += 'findstr /s /i "' + ALLTRIM( h['searchstring'] ) + '"  *.prg > results.txt' + CRLF
    cText += "REM Löschen der Lock-Datei" + CRLF
    cText += "del results.lock" + CRLF
   
    memowrit( ALLTRIM( h['seachpath'] ) + "\volltextsuche.bat", cText )
    waitrun(  ALLTRIM( h['seachpath'] ) + "\volltextsuche.bat" , 0 )
   
    ergebnis()
   
return
//----------------------------------------------------------------------------//

function ergebnis
        h['results'] := memoread( ALLTRIM( h['seachpath'] ) + "\results.txt")
        h['aZeilen'] := {}
        h['nAt'] := 0
        h['cSuche'] := CRLF
       
        do while .t.
            h['nAt'] := At(h['cSuche'], h['results'] )
            if h['nAt'] = 0
                exit
            endif
            h['cTmp'] := substr( h['results'], h['nAt'] + len( h['cSuche'] ) )
            h['resultPath'] := StrToken( h['results'], 1, ":" )
            h['len_cTmp'] := len( h['resultPath'] )
            h['treffer'] := substr( h['results'], h['len_cTmp'] + 2, At( h['cSuche'], h['results'] ) - (h['len_cTmp'] + 2) )
           
            AADD( h['aZeilen'], { h['resultPath'] , h['treffer'], h['results'] } )
           
            h['results'] := substr( h['results'], h['nAt'] + len( h['cSuche'] ) )
           
        enddo
       
        ferase( ALLTRIM( h['seachpath'] ) + "\results.txt" )
        xbrowse( h['aZeilen'] )
       
        h['oDlg']:End()
   
return nil
//----------------------------------------------------------------------------//

 



Image

Here's a basic overview of how to use findstr:

Basic Usage: At its simplest, you can use findstr to search for a string in a file. For example, to search for the word "example" in a file called "myfile.txt," you would use the following command:

findstr "example" myfile.txt

Regular Expressions: findstr supports regular expressions, which allows for more complex search patterns. For example, to find lines containing numbers, you might use:

findstr "[0-9]" myfile.txt

Multiple Files: You can search across multiple files by specifying more than one file name or using wildcards. For example, to search for "example" in all text files in the current directory, you would use:

findstr "example" *.txt

Piping and Redirection: findstr can be used with piping (|) to filter the output of another command. For example, to find which files in a directory contain the word "example," you could use:

dir | findstr "example"

Case Sensitivity: By default, findstr is case-sensitive. You can make your search case-insensitive using the /I switch. For example:

findstr /I "example" myfile.txt

Line Numbers: To include line numbers in the output, use the /N switch. For example:

findstr /N "example" myfile.txt

Re: Fulltext-Search

PostPosted: Fri Mar 15, 2024 9:43 am
by Antonio Linares

Re: Fulltext-Search

PostPosted: Sun Mar 17, 2024 9:22 am
by Otto
Hello friends,
I conducted further tests. For reference, I used TC. Here are the values for the same search.

TC 1.40 min

findstr 40 sec = command prompt

ps 15 sec

Get-ChildItem -Path c:\www\htdocs -Recurse -Filter *.prg | Select-String -Pattern "AP_GetPairs()" | ForEach-Object { $_.Path }

I think I'll continue with PowerShell.
Best regards,
Otto

Re: Fulltext-Search

PostPosted: Sun Mar 17, 2024 4:56 pm
by Otto
Hello friends,
The search with PowerShell works really well.
How did you solve the full-text search?


Best regards,
Otto

Code: Select all  Expand view


function volltxtSearch()
        local cText := ""
    
        cText :=  'Get-ChildItem -Path ' + ALLTRIM( h['seachpath'] ) + ' -Recurse -Filter ' + ALLTRIM(h['seachpattern']) + ' | Select-String -Pattern "' + ALLTRIM( h['searchstring'] ) +  '" | ForEach-Object { $_.Path } > ' + 'mysearch_results.txt'   + CRLF
        memowrit( ".\psfiles\ps_search.ps1", cText )
        waitrun( "powershell.exe -ExecutionPolicy Bypass -File .\psfiles\ps_search.ps1" )
       
        ergebnis() 
        ? "Ende"
         
return
//----------------------------------------------------------------------------//

 

Re: Fulltext-Search

PostPosted: Mon Mar 18, 2024 7:26 am
by Otto
Hello freinds,

To search in different file types such as *.prg, *.html, and *.docx, you can combine multiple Get-ChildItem commands, each with a different filter, and merge the results with the pipeline operator (|).


Best regards,
Otto

Code: Select all  Expand view

(Get-ChildItem -Path c:\Entwicklung_2012 -Recurse -Filter *.prg) +
(Get-ChildItem -Path c:\Entwicklung_2012 -Recurse -Filter *.html) +
(Get-ChildItem -Path c:\Entwicklung_2012 -Recurse -Filter *.docx) |
Select-String -Pattern "webview" |
ForEach-Object { $_.Path } |
Set-Content -Path "mysearch_results.txt" -Encoding ASCII




 

Re: Fulltext-Search

PostPosted: Mon Mar 18, 2024 8:16 am
by Otto
If you want to read the result.txt with memoread you need to use : Out-File -FilePath "search_results.txt" -Encoding ASCII'

Code: Select all  Expand view


cText :=  'Get-ChildItem -Path ' + ALLTRIM( h['seachpath'] ) + ' -Recurse -Filter ' + ALLTRIM(h['seachpattern'])
        cText +=  ' | Select-String -Pattern "' + ALLTRIM( h['searchstring'] )
        cText += '" | ForEach-Object { $_.Path } | Out-File -FilePath "search_results.txt" -Encoding ASCII'   + CRLF
     

 

Re: Fulltext-Search

PostPosted: Wed Mar 20, 2024 9:34 am
by Otto
Hello friends,
I am changing the input dialog for the full-text search to webview.
Best regards,
Otto

Image