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 RUN
#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
//----------------------------------------------------------------------------//
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