问题
I'm new to batch scripts so I would appreciate commented solution if possible. I'm looking for a bat script that would search set directory c:\in containing XML files for files that contain "xyz" string (in them, not in their filename). Once the file with "xyz" is found it should be copied to another location c:\out . For illustration purposes all of XML files have the same structure and the string (that files should be search for) is within the tag .
回答1:
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN ('findstr /m /L "xyz" "%sourcedir%\*.xml"') DO (
echo(COPY "%%a" "%destdir%\%%~nxa"
)
GOTO :EOF
You would need to change the settings of sourcedir
and destdir
to suit your circumstances.
The required COPY commands are merely ECHO
ed for testing purposes. After you've verified that the commands are correct, change ECHO(COPY
to COPY
to actually copy the files. Append >nul
to suppress report messages (eg. 1 file copied
)
simply, gather the output of findstr
searching for literal xyz
in %sourcedir%\*.xml
into %%a
. The /m
switch outputs the filenames found containing the string. Construct the appropriate copy
command using ~nxa
to select just the name and extension.
回答2:
This code is inspired from Local_Search_Engine.bat
@ECHO OFF
Title Scan a folder and Search a string in XML-files by (c) Hackoo 2016
mode con cols=75 lines=2
Call :init
Call :inputbox "Please enter something to search :" "Search a string in multi-files by (c) Hackoo 2016"
If "%input%" == "" Color 0C & (
echo(
echo You must enter a string to continue with this program
pause>nul & exit
) else (
Call :Browse4Folder "Choose source folder to scan for %input%" "c:\scripts"
)
::******************************************************************************************
Set "ROOT=%Location%"
::Does string have a trailing back slash ? if so we remove it !
IF %ROOT:~-1%==\ SET ROOT=%ROOT:~0,-1%
Set "NewFolder2Copy=%userprofile%\Desktop\NewCopyXMLFiles"
SET "EXT=xml"
SET "Count=0"
set "Word2Search=%input%"
Set "LogFile=%~dp0%~n0_%Word2Search%.txt"
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"
Call :PS_Sub 'information' 10 '"Scanning now for """%Word2Search%""" on """*.%%a""" . . . "' "'Please wait. . . Scan is in progress on all """*.%%a""" . . .'" 'info' 5
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% + 24
rem If %cols% LSS 50 set /a cols=%cols% + 15
set /a lines=%Count% + 12
Mode con cols=%cols% lines=%lines%
echo(
Call :color 0A " ------------------------------------------------" 1
ECHO Folder : "%ROOT%"
Call :color 0A " ------------------------------------------------" 1
rem 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.
Call :color 0D " Type the number of file that you want to explore" 1
echo(
Call :color 0C " To save those files just hit 'S'" 1
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
::***************************************************************************
:InputBox
set "input="
set "heading=%~2"
set "message=%~1"
echo wscript.echo inputbox(WScript.Arguments(0),WScript.Arguments(1)) >"%temp%\input.vbs"
for /f "tokens=* delims=" %%a in ('cscript //nologo "%temp%\input.vbs" "%message%" "%heading%"') do (
set "input=%%a"
)
exit /b
::***************************************************************************
:PS_Sub $notifyicon $time $title $text $icon $Timeout
PowerShell ^
[reflection.assembly]::loadwithpartialname('System.Windows.Forms') ^| Out-Null; ^
[reflection.assembly]::loadwithpartialname('System.Drawing') ^| Out-Null; ^
$notify = new-object system.windows.forms.notifyicon; ^
$notify.icon = [System.Drawing.SystemIcons]::%1; ^
$notify.visible = $true; ^
$notify.showballoontip(%2,%3,%4,%5); ^
Start-Sleep -s %6; ^
$notify.Dispose()
%End PowerShell%
exit /B
::****************************************************************************
:Browse4Folder
set Location=
set vbs="%temp%\_.vbs"
set cmd="%temp%\_.cmd"
for %%f in (%vbs% %cmd%) do if exist %%f del %%f
for %%g in ("vbs cmd") do if defined %%g set %%g=
(
echo set shell=WScript.CreateObject("Shell.Application"^)
echo set f=shell.BrowseForFolder(0,"%~1",0,"%~2"^)
echo if typename(f^)="Nothing" Then
echo wscript.echo "set Location=Dialog Cancelled"
echo WScript.Quit(1^)
echo end if
echo set fs=f.Items(^):set fi=fs.Item(^)
echo p=fi.Path:wscript.echo "set Location=" ^& p
)>%vbs%
cscript //nologo %vbs% > %cmd%
for /f "delims=" %%a in (%cmd%) do %%a
for %%f in (%vbs% %cmd%) do if exist %%f del /f /q %%f
for %%g in ("vbs cmd") do if defined %%g set %%g=
goto :eof
::****************************************************************************
:init
prompt $g
for /F "delims=." %%a in ('"prompt $H. & for %%b in (1) do rem"') do set "BS=%%a"
exit /b
::****************************************************************************
:color
set nL=%3
if not defined nL echo requires third argument & pause > nul & goto :eof
if %3 == 0 (
<nul set /p ".=%bs%">%2 & findstr /v /a:%1 /r "^$" %2 nul & del %2 2>&1 & goto :eof
) else if %3 == 1 (
echo %bs%>%2 & findstr /v /a:%1 /r "^$" %2 nul & del %2 2>&1 & goto :eof
)
exit /b
::***************************************************************************
回答3:
Try This:
@echo on
set "BaseDir=folder_containing_xml_files"
set "DestDir=destination_dir"
set "ListFile=%userprofile%\Desktop\list.txt"
for /F "usebackq tokens=*" %%A in ("%ListFile%") do copy "%BaseDir%\%%~A" "%DestDir%"
pause
create list.txt
on your desktop then type xyz.xml
(filename) into list.txt
. Then save the file. Edit the paths of the batch and then run.
来源:https://stackoverflow.com/questions/39577430/search-xml-files-in-directory-for-specific-string-then-do-copy-action-using-bat