I'm trying to loop through all .lss files in a folder, and grab a string that exists between two tags, save that value and rename the file using that string.
Example:
42982934829.lss -> contains string:
<surveyls_title><![CDATA[J.3200-1118 - Project Title]]></surveyls_title>
Rename to `J.3200-1118 - Project Title.lss`
Here is what I have so far, but I fear my syntax is badly incorrect..
#Echo off
Set Folder=X:\RenameTest
Set Files=*.lss
PushD %Folder%
For %%A in (%Files%) Do For /f %%B IN (
'findstr "<surveyls_title>.*</surveyls_title>" "%ProjectTitle%"'
) Do Call :Rename ..
PopD
Goto :Eof
:Rename
Echo Ren %1 "%ProjectTitle%"
I suppose this is what you want.
#echo off
pushd "X:\RenameTest"
for %%a in (*.lss) do for /f "tokens=3*delims=[]" %%i in ('type "%%a" ^| find "</surveyls_title>"') do echo ren "%%~a" "%%~i%%~xa"
popd
Just remove echo from the line once you are happy with the printed results.
You can also extract the title using Regex : Demo Here
#echo off & color 0A
Title Extract Title using Regex
Set "InputFile=42982934829.lss"
Call :Extract_Title "%InputFile%" Title
Echo %Title%
Pause & Exit
::----------------------------------------------------------------------------------------
:Extract_Title <InputFile> <Title to be Set>
(
echo WScript.StdOut.WriteLine Extract_Title(Data^)
echo Function Extract_Title(Data^)
echo Data = WScript.StdIn.ReadAll
echo Set re = New RegExp
echo re.Global = True
echo re.IgnoreCase = True
echo re.Pattern = "\[CDATA\[(.*?)\]\]"
echo For Each Match in re.Execute(Data^)
echo Title = Match.SubMatches(0^)
echo Next
echo Extract_Title = Title
echo End Function
)>"%tmp%\%~n0.vbs"
for /f "delims=" %%A in ('cscript /nologo "%tmp%\%~n0.vbs" ^< "%~1"') do set "%2=%%A"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
Exit /B
::----------------------------------------------------------------------------------------
Related
I want to read the file name with the command and automatically move it to the folder with the same name. What should I do?
example:
before processing
after processing
If I have files and folders with the same name, I want to move them to a folder with the same name.
What should I do? Do I have a cmd command?
I will provide both a solution to this exact question, and an alternative that I would suggest to handle this situation.
==========
~ Solution ~
==========
Copy/Paste the code below into an empty file, save, and execute.
#echo off
for /f "tokens=1,* delims=_" %%a in ('dir /b *.xlsx') do (
if not "%%a_%%b"=="%~nx0" (
if not exist %%a mkdir %%a
move "%%a_%%b" "%%a\"
)
)
You can change the "*.xlsx" to any other file extension, or change to "*.*" to work with ANY file extension.
Keep in mind though, this ONLY works with filenames that are formatted like the way you mentioned in your question.
===================
~ Alternative Solution~
===================
I would suggest the Shell Extension "Files 2 Folder" as an alternative. I came across a situation where I needed something similar to what you're asking a couple years ago, and this ended up working out great.
https://www.dcmembers.com/skwire/download/files-2-folder/
Here is another approach using regex in vbscript with a batch file :
#echo off & color 0A
Title Extract Title using Regex in vbscript
SetLocal EnableDelayedExpansion
#for /f "delims=" %%a in ('dir /b *.xlsx') do (
Call :Extract_Title "%%a" Title
If Defined Title (
If Not Exist "!Title!\" MkDir "!Title!\"
Move /-Y "%%a" "!Title!\"
)
)
Pause & Exit
::----------------------------------------------------------------------------------------
:Extract_Title <InputFile> <Title to be Set>
>"%tmp%\%~n0.vbs" (
echo WScript.StdOut.WriteLine Extract_Title(Data^)
echo Function Extract_Title(Data^)
echo Data = Wscript.Arguments(0^)
echo Set re = New RegExp
echo re.Global = True
echo re.IgnoreCase = True
echo re.Pattern = "(\S+|\S.+)_"
echo For Each Match in re.Execute(Data^)
echo Title = Match.SubMatches(0^)
echo Next
echo Extract_Title = Title
echo End Function
)
#for /f "delims=" %%A in ('cscript /nologo "%tmp%\%~n0.vbs" "%~1"') do set "%2=%%A"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
Exit /B
::----------------------------------------------------------------------------------------
I am a newbie to Windows Scripting.
I am trying to list some txt files in several sub directories & want to copy a user selected file to a new destination. Please note that the file name is unique in different locations.
I got the first part to work (Listing out the files & locations) using the following script, but I am unable to copy the selected file to the new location.
#ECHO OFF
SET index=1
SETLOCAL ENABLEDELAYEDEXPANSION
SET FFPath="C:\Scripts - Backup Server\DKXpress_bkp"
SET NewPath=C:\DKServer
ECHO Recursively searching %FFPath%
echo.
FOR /F "delims=" %%f in ('DIR %FFPath%\*.txt /a:-d /s /b') DO (
SET file!index!=%%f
ECHO !index! - %%f
SET /A index=!index!+1
)
SETLOCAL DISABLEDELAYEDEXPANSION
SET /P selection="select file by number:"
SET file%selection% >nul 2>&1
IF ERRORLEVEL 1 (
ECHO invalid number selected
EXIT /B 1
)
SET NewFile=file%selection%
ECHO Copying %NewFile% to %NewPath%
ECHO.
COPY /Y "%NewFile%" "%NewPath%"
ECHO.
PAUSE
I think I am doing this part wrong
SET NewFile=file%selection%
Thank you all in advance
You don't need to set an index variable or delayed expansion, if you let Find do the work for you:
#Echo Off
Set "FFPath=C:\Scripts - Backup Server\DKXpress_bkp"
Set "NewPath=C:\DKServer"
Echo Recursively searching %FFPath%
Echo=
For /F "Delims==" %%A In ('"Set File[ 2>Nul"') Do Set "%%A="
For /F "Tokens=1* Delims=]" %%A In (
'"Dir /B/S/A-D-S-L "%FFPath%\*.txt" 2>Nul|Find /N /V """') Do (
Echo %%A] %%B
Set "File%%A]=%%B"
)
Echo=
Set /P "#=Select file by number: "
Echo=
For /F "Tokens=1* Delims==" %%A In ('"Set File[%#%] 2>Nul"') Do (
Echo Copying %%B to %NewPath%&Echo=
Copy /Y "%%B" "%NewPath%"
GoTo :End
)
Echo Invalid number selected
:End
Echo=
Pause
You need to use delayed expansion to get the file name assigned to the variable correctly.
SET NewFile=!file%selection%!
Remove the setlocal to disable delayed expansion.
You can try something like that :
#ECHO OFF
:Main
cls
SET index=1
SETLOCAL ENABLEDELAYEDEXPANSION
SET FFPath="C:\Scripts - Backup Server\DKXpress_bkp"
SET "NewPath=C:\DKServer"
ECHO Recursively searching %FFPath%
echo.
FOR /F "delims=" %%f in ('DIR %FFPath%\*.txt /a:-d /s /b') DO (
SET filepath[!index!]=%%f
ECHO [!index!] - %%~nxf - %%f
SET /A index=!index!+1
)
echo(
echo select file by number :
set /p Input=""
For /L %%i in (1,1,%index%) Do (
If "%INPUT%" EQU "%%i" (
ECHO Copying "!filepath[%%i]!" to "!NewPath!"
COPY /Y "!filepath[%%i]!" "!NewPath!"
)
)
echo Copying another file ? (Y = Yes or N = No) ?
set /p input2=""
If /I "!input2!"=="Y" (
goto :Main
) else (
goto :eof
)
I tried to write a batch script that find all the paths of files that have the same name as the input string. right now it can find only the first file found, and i cant think of a way to make it list multiple files locations. I am not very experienced and I need some help.
this is part of the script code:
:start
cls
echo Enter file name with extension:
set /p filename=
echo Searching...
for %%a in (C D E F G H U W) do (
for /f "tokens=*" %%b in ('dir /s /b "%%a:\%filename%"') do (
set file=%%~nxb
set datapath=%%~dpb\
::the path of the file without the filename included "C:\folder\folder\"
set fullpath=%%b
::the path of the file with the filename included "C:\folder\folder\file"
goto break
)
)
:notfound
cls
echo Enter file name with extension:
echo %filename%
echo File Not Found!
ping localhost -n 4 >nul
goto start
:break
if "%datapath:~-1%"=="\" set datapath=%datapath:~,-1%
cls
echo 3 %filename% found
echo %fullpath1%
echo %fullpath2%
echo %fullpath3%
--- || ---
I want the script to search the computer and list every encountered files with the same name and I want to be able to put those files' paths into different variables.
For example, if readme.txt is the input, then I want the list of all the paths of all the files with that specific name (readme.txt) and I want to set variable for each path so I can use it after that.
input:
readme.txt
output:
3 files found
C:\folder\folder\readme.txt
C:\folder\folder\folder\readme.txt
D:\folder\readme.txt
#echo off
set filename=readme.txt
for %%a in (C D E F G H U W) do (
for /f "tokens=*" %%b in ('dir /s /b "%%a:\%filename%"') do (
echo you can do something here with %%~nxb in %%~dpb
echo full name: %%b
)
)
I see no need to set the filenames to variables, as you can process them inside your loop. But if you really need them (for some reason) in variables:
#echo off
setlocal enabledelayedexpansion
set filename=readme.txt
set count=0
for %%a in (C D E F G H U W) do (
for /f "tokens=*" %%b in ('dir /s /b "%%a:\%filename%" 2^>nul') do (
set /a count+=1
set _file[!count!]=%%b
)
)
set _file
You can try with this code :
#echo off
Title Searching for the path with the same file name
Mode con cols=80 lines=3 & Color 9E
SET /a Count=0
set /a cnt=1
set "FileName=Readme.txt"
set "Report=%~dp0Report.txt"
set "Folder2Copy=%~dp0Readme_Folder"
set "Result2Copy=%~dp0Result2Copy.txt
If exist %Folder2Copy% RD /S /Q %Folder2Copy%
If Exist %Report% Del %Report%
If Exist %Result2Copy% Del %Result2Copy%
echo(
Echo Searching for the path with the same file name
Rem Looking for fixed drives and store them into variables
SETLOCAL enabledelayedexpansion
For /f "skip=1" %%a IN ('wmic LOGICALDISK where driveType^=3 get deviceID') DO (
for /f "delims=" %%b in ("%%a") do (
SET /a "Count+=1"
set "Drive[!Count!]=%%b"
)
)
:Display
for /L %%i in (1,1,%Count%) do (
cls
Title Please wait a while ... Searching for "%FileName%" on "!Drive[%%i]!\"
echo(
echo Please wait a while ... Searching for "%FileName%" on "!Drive[%%i]!\"
Call :FindPathFile !Drive[%%i]!\ %FileName% >> %Report%
)
Start "" %Report%
Goto :AskQuestion
::***************************************************************************************
:FindPathFile <Location> <FileName>
Where.exe /r %1 %2
Goto :eof
::***************************************************************************************
:AskQuestion
cls & Mode con cols=100 lines=5
echo(
echo Did you want to make copy of all files found as name "%FileName%"
echo saved on "%Report%" ? (Y/N) ?
set /p "Input="
If /I "%INPUT%"=="Y" (
for /f "delims=" %%i in ('Type "%Report%"') do (
Call :MakeCopy "%%~i" "%Folder2Copy%\"
)
)
Call :Explorer "%Folder2Copy%\" & exit
If /I "%INPUT%"=="N" (
Exit
)
Goto :eof
::***************************************************************************************
:MakeCopy <Source> <Target>
If Not Exist "%~2\" MD "%~2\" (
if not exist "%2\%~n1" (
echo copying "%~1" to "%~2"
copy /N /B "%~1" "%~2" >>%Result2Copy% 2>&1
) else (
call :loop "%~1" "%~2"
)
)
::***************************************************************************************
:loop
set "fname=%2\%~n1(%cnt%)%~x1"
if exist "%fname%" set /a cnt+=1 && goto :loop
copy "%~1" "%fname%"
exit /b
::***************************************************************************************
:Explorer <file>
explorer.exe /e,/select,"%~1"
Goto :EOF
::***************************************************************************************
I have the following file contents from which I want to extract the MD5 hash value thats on line 2.
How can I do this in a Windows batch file? Unfortunately using powerscript is not an option.
Herewith the input file ( file.txt )
MD5hashoffile20160613190010_Address
f4f855c5cb40767a7227b506f641ceef
CertUtil:-hashfilecommandcompletedsuccessfully.
I wanted to use the findstr utility but the regex I use must be wrong since it's not returning anything.
findstr /R "[a-fA-F0-9]{32}" file.txt
I appreciate any advice.
Thanks
UPDATE :
I have added the full solution in the answer section.
After some trial and error I found a solution that works :
findstr /R "^[a-fA-F0-9]*$" file.txt
Updated Answer with full solution :
SETLOCAL ENABLEDELAYEDEXPANSION
SET "FILESIZE=0"
SET "RECORDCOUNT=0"
SET "MD5HASH="
SET "TEMPHASH="
SET "FILESETREPORT=_UNSET"
SET "LINE=0"
SET "COLUMNS=TableName|RecordCount|FileSize|FileHash"
echo "============================="
echo "= Starting FileSize process ="
echo "============================="
for %%F in (*.csv) do (
echo "Process A CSV File"
for /f "tokens=1,2,3,4 delims=^_" %%A IN ("%%~nF") do (
SET "TABLENAME=%%D"
SET "FILESIZE=%%~zF"
if "!FILESETREPORT!" == "_UNSET" (
SET "FILESETREPORT=%%A_%%B_%%C_FilesetReport.csv"
:: Initialize the headers
echo !COLUMNS! > !FILESETREPORT!
)
)
echo "Get RecordCount in CSV"
if "!TABLENAME!" NEQ "FilesetReport" (
for /f "tokens=*" %%I in ('more +1 %%F ^| find /v /c ""') do SET "RECORDCOUNT=%%I"
echo "Generate File MD5 Hash"
certUtil -hashfile %%~nxF MD5 > hashfile
echo "Get the hash from the file"
for /f "skip=1 tokens=*" %%A in (hashfile) do (
SET "TEMPHASH=%%A"
:: call :cleanHash
if !LINE! == 0 SET "LINE=1" && call :cleanHash
)
:: Reset the Line Number
SET "LINE=0"
echo "Save File Details to FieldsetReport"
echo "RecordCount : !RECORDCOUNT!"
echo "FileSize : !FILESIZE!"
echo "MD5Hash : !MD5HASH!"
echo "TableName : !TABLENAME!"
SET "OUTPUTLINE=!TABLENAME!|!RECORDCOUNT!|!FILESIZE!|!MD5HASH!"
echo !OUTPUTLINE! >> !FILESETREPORT!
:: Cleanup
del hashfile
)
)
echo "File Processing Completed"
exit /b 0
:cleanHash
echo "Remove all spaces from the MD5 hash"
:: for /f "delims=" %%a in ('findstr /R "^[a-fA-F0-9]*$" !TEMPHASH!') do SET TEMPHASH=%%a
SET "MD5HASH=!TEMPHASH: =!"
echo "********************************************************************"
echo !MD5HASH!
ENDLOCAL
You're better off using this:
#echo off
for /f "skip=1" %%a in (file.txt) do set "hash=%%a" &goto breakLoop
:breakLoop
echo %hash%
pause
This should work even if another line also contains only hexadecimal characters, and has the added benefit of putting the md5 hash in a variable, ready to be used.
I am trying to replace a line in load.xml using the lines read from FileList.txt.
Contents of load.xml
<mainheader>
<InFilePath>D:\Data\All_Inputfiles\oldfile.txt</InFilePath>
</mainheader>
FileList.txt
newfile1.txt
newfile2.txt
Expecting the output with each iteration as
<mainheader>
<InFilePath>D:\Data\All_Inputfiles\newfile1.txt</InFilePath>
</mainheader>
and with the next iteration replace newfile1.txt with newfile2.txt. I am able to get original string with the final string but last part of the code is throwing syntax error, i.e. from
for /f "delims=" %%a in (!INTEXTFILE!) do call :Change "%%a" .
Could please help me?
Thanks in advance.
#echo off
SETLOCAL EnableDelayedExpansion
Set AllInputFile= D:\data\FileList.txt
SET INTEXTFILE=C:\c:\load.xml
set OUTTEXTFILE=D:\data\tmp_out.txt
SET BackupPath=D:\data\backupload.xml
Set TempFile=D:\data\tmp.txt
SET DbgFile=D:\data\debuginfo.txt
Del !TempFile!
Del !DbgFile!
Copy !INTEXTFILE! !BackupPath!
:replace
findstr /g "InFilePath" !INTEXTFILE!>!TempFile!
:: set string=" <InFilePath>D:\Data\All_Inputfiles\oldfile.txt</InFilePath>"
set /p string=< !TempFile!
SET PREVFILE_NM=!string:~75,-13!
set FinalreplaceLine=!string!
set TARG_FILE=%~1
REM ECHO "Before Replace FinalreplaceLine "!FinalreplaceLine!>>!DbgFile!
set FinalreplaceLine=!FinalreplaceLine:%PREVFILE_NM%=%TARG_FILE%!
ECHO "string "!string!>>!DbgFile!
ECHO "FinalreplaceLine "!FinalreplaceLine!>>!DbgFile!
::string has source string and FinalreplaceLine has target string to replace
for /f "delims=" %%a in (!INTEXTFILE!) do call :Change "%%a"
exit /b
:Change
set Text=%~1
if "%Text%"=="%string%" (
(echo !FinalreplaceLine!)>> !OUTTEXTFILE!
) else (
(echo !Text!)>> !OUTTEXTFILE!
)
exit /b
Does this work for you?:
#echo off
for /f "usebackq delims=" %%a in ("FileList.txt") do (
call :change "%%a"
type "load.xml"
pause
)
echo done
pause
goto :EOF
:change
(
echo ^<mainheader^>
echo ^<InFilePath^>D:\Data\All_Inputfiles\%~1^</InFilePath^>
echo ^</mainheader^>
) > "load.xml"