-1

I have a folder with many .txt files. I would like to find string "X" in all of these files then I would like to copy the found strings into .txt files into a different folder.

So far I have tried :

@echo on
findstr /m "X" "%userprofile%\Desktop\New_Folder\New_Folder\*.txt"
if %errorlevel%==0 do (
for %%c in (*.txt) do (
type %%c >> "%UserProfile%\Desktop\New_Folder\%%~nc.txt"
pause

I do not understand the output %%~nc.txt part it's suppost to copy the changed .txt files to a new folder with the same name.

I would like to point out that string "X" is found in different places in the .txt file.

MALKAVIAN
  • 131
  • 14
  • I don't know what `%%~vc` is; type `for /?` into a command prompt window and read the help; there is no `~v` modifier (there is no `for %%v` loop either). Anyway, your code is incomplete as there are unbalanced parentheses... And what about typing the few characters of your requirements into here as text rather than providing them as picture? – aschipfl Sep 16 '16 at 14:23
  • @aschipfl I like to be creative. Thanks for `for /?` I'll take a squiz. – MALKAVIAN Sep 16 '16 at 14:28
  • As far as I'm concerned, the image shows a non capitalised **x**, not a capitalised **X** as per your search. Additionally I would consider **x** as a character, only becoming a string if it appears adjacent only to whitespace, (string1 **x** string3). This sort of information is vital when attempting to formulate worthwhile solutions. – Compo Sep 16 '16 at 14:55
  • @Compo `X = anystring` such as abcd123moronqwop capital or not it's unknown. – MALKAVIAN Sep 16 '16 at 15:03
  • regardless of you asking for a search on **x**, when you weren't looking for a string x, you should have still stipulated whether that string is inclusive or exclusive. You should also note that findstr in a batch file will not be able to perform this task on any string you decide to replace for the x you used. I would suggest you think about using another scripting language. – Compo Sep 16 '16 at 15:21
  • 1
    Could you provide some sample data/files (both source and target)? – aschipfl Sep 16 '16 at 20:20
  • @aschipfl - The `for /?` command you gave me is great it explains a lot. Thanks! :-) – MALKAVIAN Sep 20 '16 at 12:47

3 Answers3

2

This batch file can did the trick (-_°)

So, just give a try : ScanfilesWordSearch_X.bat

@ECHO OFF
::******************************************************************************************
Title Scan a folder and store all files names in an array variables
SET "ROOT=%userprofile%\Desktop"
Set "NewFolder2Copy=%userprofile%\Desktop\NewCopyTxtFiles"
SET "EXT=txt"
SET "Count=0"
Set "LogFile=%~dp0%~n0.txt"
set "Word2Search=X"
SETLOCAL enabledelayedexpansion
REM Iterates throw the files on this current folder and its subfolders.
REM And Populate the array with existent files in this folder and its subfolders
For %%a in (%EXT%) Do ( 
    Call :Scanning "%Word2Search%" "*.%%a"
    FOR /f "delims=" %%f IN ('dir /b /s "%ROOT%\*.%%a"') DO (
        ( find /I "%Word2Search%" "%%f" >nul 2>&1 ) && (
            SET /a "Count+=1"
            set "list[!Count!]=%%~nxf"
            set "listpath[!Count!]=%%~dpFf"
        )
    ) || (
            ( Call :Scanning "%Word2Search%" "%%~nxf")
    )
)
::***************************************************************
:Display_Results
cls & color 0B
echo wscript.echo Len("%ROOT%"^) + 20 >"%tmp%\length.vbs"
for /f %%a in ('Cscript /nologo "%tmp%\length.vbs"') do ( set "cols=%%a")
If %cols% LSS 50 set /a cols=%cols% + 20
set /a lines=%Count% + 10
Mode con cols=%cols% lines=%lines%
ECHO  **********************************************************
ECHO  Folder:"%ROOT%"
ECHO  **********************************************************
If Exist "%LogFile%" Del "%LogFile%"
rem Display array elements and save results into the LogFile
for /L %%i in (1,1,%Count%) do (
    echo [%%i] : !list[%%i]!
    echo [%%i] : !list[%%i]! -- "!listpath[%%i]!" >> "%LogFile%"     
)

(   
    ECHO.
    ECHO Total of [%EXT%] files(s^) : %Count% file(s^) that contains the string "%Word2Search%"
)>> "%LogFile%"
ECHO(
ECHO Total of [%EXT%] files(s) : %Count% file(s)
echo(
echo    Type the number of file that you want to explore 
echo(
echo        To save those files just hit 'S' 
set /p "Input="
For /L %%i in (1,1,%Count%) Do (
    If "%INPUT%" EQU "%%i" (
        Call :Explorer "!listpath[%%i]!"
    )
    IF /I "%INPUT%"=="S" (
        Call :CopyFiles
    )
)   
Goto:Display_Results
::**************************************************************
:Scanning <Word> <file>
mode con cols=75 lines=3
Cls & Color 0E
echo(
echo         Scanning for the string "%~1" on "%~2" ...
goto :eof
::*************************************************************
:Explorer <file>
explorer.exe /e,/select,"%~1"
Goto :EOF
::*************************************************************
:MakeCopy <Source> <Target>
If Not Exist "%~2\" MD "%~2\"
Copy /Y "%~1" "%~2\"
goto :eof
::*************************************************************
:CopyFiles
cls
mode con cols=80 lines=20
for /L %%i in (1,1,%Count%) do (
    echo Copying "!list[%%i]!" "%NewFolder2Copy%\"
    Call :MakeCopy  "!listpath[%%i]!" "%NewFolder2Copy%">nul 2>&1 
)
Call :Explorer "%NewFolder2Copy%\"
Goto:Display_Results
::*************************************************************
Hackoo
  • 18,337
  • 3
  • 40
  • 70
1
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "mystring=x"
FOR %%a IN ("%sourcedir%\*.txt") DO FINDSTR "%mystring%" "%%a">nul&IF NOT ERRORLEVEL 1 FINDSTR "%mystring%" "%%a">"%destdir%\%%~nxa"

GOTO :EOF

You would need to change the settings of sourcedir and destdir to suit your circumstances and set mystring appropriately, noting that you may have to adjust the findstr switches to accomodate case, literal and space-in-target-string.

Naturally, you could code sourcedir etc. directly as literals, but doing it this way means that the relevant strings need only be changed in one place.

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

You are close, but checking the ErrorLevel of findstr does not make sense here as this reflects the overall result, that is, ErrorLevel is set to 0 in case any of the files contain the search string.

I would parse the output of findstr /M using a for /F loop and copy the returned files in the body:

for /F "eol=| delims=" %%F in ('
    findstr /M /I /C:"X" "%USERPROFILE%\Desktop\New_Folder\New_Folder\*.txt"
') do (
    copy "%%F" "%USERPROFILE%\Desktop\New_Folder\"
)

This copies all those files which contain the literal search string (in a case-insensitive manner).

aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • [EDIT](http://stackoverflow.com/revisions/39534388/2): added `/I` switch to do case-insensitive search; added `/C` switch to treat search string as a literal one; – aschipfl Sep 16 '16 at 15:18
  • just to note this is what the OP asked, "I would like to find string "X" in all of these files then I would like to copy the found strings into .txt files into a different folder." The image asks that they are copied "with only string x in them". I'm assuming that the question asks for the file name with the matching string to be copied over but in doing so the destination file will only contain the matching string*(s)*. – Compo Sep 16 '16 at 15:29
  • @Compo, I agree, it is not absolutely clear what is needed; anyway, I am copying all those files containing the search string... – aschipfl Sep 16 '16 at 15:33
  • What Compo assumes is true. I figured that `%%~vc.txt` would be the key to copying the `.txt` file names as is over into the new folder. I took `%%~nc.txt` and made it `%%~vc.txt` not knowing that `~n` had significant value. – MALKAVIAN Sep 16 '16 at 19:19