Reputation: 177
Does there exist a command line utility for Windows that can search text more sophisticated than FIND and FINDSTR? Something that will find all lines of text that contain specified keywords no matter the order of words?
For example, if the keywords are "Happily Ever After" it should find lines containing "Ever After Happily" and "If ever that happens after today, she will happily embrace it", but not "happily together".
Upvotes: 0
Views: 145
Reputation: 130819
I like Mee's answer, as it uses only native commands. However, it must read the file once for each word to search. This might slow things down if you add a large number of additional tests.
You could use my JREPL.BAT hybrid Jscript/batch regex utility, coupled with a bit of user supplied JScript, and get an efficient and robust solution that produces the result with a single pass through the text. JREPL is pure script that runs natively on any Windows machine from XP onward. Full documentation is embedded within the script, and can be accessed via jrepl /?
, or jrepl /??
for paged output.
Here is one possible solution using JREPL. I initialize variables a
, b
, and c
to 0, then on each line I search for the required words, and each word sets a different variable to 1 if found. The replacement string must also replace the found word with itself. At the end of each line I disable printout of the line if the sum of a+b+c <> 3
, and then I reset all three variables to 0 in preparation for the next line. The /F
option at the end specifies that I am searching file "test.txt". I use line continuation to make the long command easier to read.
call jrepl "\b(?:(happily)|(ever)|(after))\b"^
"if ($1) a=1; else if ($2) b=1; else c=1; $0"^
/jbeg "var a=0,b=0,c=0"^
/jendln "if (a+b+c!=3) $txt=false; a=b=c=0"^
/j /i /f test.txt
Below is another solution that uses the same basic logic, except I use the /T option to simplify the code a bit. The /T option is similar to the Oracle Translate() function, or the unix tr command, or the sed y command.
call jrepl "\bhappily\b \bever\b \bafter\b"^
"a=1;$0 b=1;$0 c=1;$0"^
/jbeg "var a=0,b=0,c=0"^
/jendln "if (a+b+c!=3) $txt=false; a=b=c=0"^
/j /i /t " " /f test.txt
Upvotes: 1
Reputation: 207
type search.txt | findstr /i /r "\<happily\>" | findstr /i /r "\<ever\>" | findstr /i /r "\<after\>"
I used the test case...
search.txt:
Happily Ever After
Happily Ever After blah
blah Happily Ever After
Happily Ever blah After
If ever that happens after today, she will happily embrace it
happily together
happily
ever
after
happily ever
ever after
after happily
every happily afterwards
And that gives output:
Happily Ever After
Happily Ever After blah
blah Happily Ever After
Happily Ever blah After
If ever that happens after today, she will happily embrace it
above only.
Is this what you needed?
Upvotes: 2