How to sort formats in batch - batch-file

This is my first question in stack overflow, I hope I'm not breaking any rules, If I do, Just tell me.
I want to do a batch to open just TXT files, And send an error while opening other file format
Example: RTF
#echo off
rem I do some jokes while coding, As put name the name "randy" to a random variable :3
set randy=%RANDOM%
if exist %1 goto 1
echo msgbox ("Corrupt or unexisting file"),16,("Project1")>"%TMP%\FC%randy%SPEECH.vbs"
CScript "%TMP%\FC%randy%SPEECH.vbs" //nologo
erase /f /q "%TMP%\FC%randy%SPEECH.vbs"
exit
:1
rem I failed at this part, This part was supposed to filter the File format.
set filetype=%~1
echo %filetype%
pause>nul
if %filetype%=="*.png" goto 2 else goto notvalid
goto fail
:2
type %1
echo.
echo Press any key to close the file
pause>nul
exit
:fail
rem I also did a section if the code fails
echo msgbox("Oops, The code did not work"),16,("Project1")>"%TMP%\FC%randy%SPEECH.vbs"
CScript "%TMP%\FC%randy%SPEECH.vbs" //nologo
erase /f /q "%TMP%\FC%randy%SPEECH.vbs"
exit
:notvalid
rem If the format is wrong
echo msgbox("This format is not compatible with the app"),16,("Project1")>"%TMP%\FC%randy%SPEECH.vbs"
CScript "%TMP%\FC%randy%SPEECH.vbs" //nologo
erase /f /q "%TMP%\FC%randy%SPEECH.vbs"
exit
I hope what you can help me.

Using this at the start will branch to your routine on other filetypes:
#echo off
if /i not "%~x1"==".txt" goto :notvalid

if /I "%filetype%"=="*.png" (goto 2) else goto notvalid
You need to use " double quotes and () parentheses properly, see IF command (note that goto fail statement will not perform at all then); /I switch for case insensitive comparing. Compare:
==>if "*.TXT"=="*.txt" dir /B xxxx2.csv else dir /B xxx.csv
==>if /I "*.TXT"=="*.txt" dir /B xxxx2.csv else dir /B xxx.csv
xxxx2.csv
xxx.csv
==>if /I "*.TXT"=="*.txt" (dir /B xxxx2.csv) else dir /B xxx.csv
xxxx2.csv
==>
And I would recommend next improvement (check whether at least one parameter is supplied):
set "randy=%RANDOM%"
if "%~1"=="" goto :notvalid
set "filetype=%~1"
if exist %1 goto 1

Related

move and Rename file to folder Powershell

I have some pdf's in a folder that I need to organize them like this:
PDF name: 123.12.123.pdf ; 102030_01.pdf; 102030_02.pdf; 123.4512.34561.23412.pdf
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern: ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001.pdf
for this I have used the following code which works very well:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
I drag the pdfs into the .bat and it does the adjustment.
It happens that there is a case that I am not able to handle. Some pdfs need to be in the same folder, for example in the following case:
PDF name: 102030_01.pdf; 102030_02.pdf;
Note that the pdfs have the same number, only after the _ that we have the difference. In this case you would need to create a folder with the name:102030
And move the two files into it, modifying their name as follows:
102030_01.pdf -> P102030_V1_A0V0_T07-54-369-664_S00001.pdf
102030_02.pdf -> P102030_V1_A0V0_T07-54-369-664_S00002.pdf
Could anyone help?
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
if /i "%basename%" neq "%basename:_=%" goto sub2
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
:sub2
for /f "tokens=1*delims=_" %%b in ("%basename%") do (
MD "%~dp1%%b" 2>NUL
ECHO Move /Y %1 "%~dp1%%b\P%basename:-=%_V1_A0V0_T07-54-369-664_S000%%c_Volume%~x1"
)
Exit /B
Always test on dummy data first.
This code echoes the proposed move. After verification, remove the echo keyword to activate.
Caution: My reading of the code is that - should be removed from the basename in the new name, and that _Volume should be appended to the name part, which is not shown in your examples.
Essentially, if the basename contains _ then goto sub2.
sub2 partitions the name in basename, assigning the first part to %%b and the second to %%c (See for /? from the prompt for documentation)
Then the directory is created
The md will object if the directory already exists, hence the 2>nul in the original code (suppresses error messages)
If md found that error in the original then this appears to be a problem, so the move is not executed. In the new version, it is expected that the directory may already exist, so the errorlevel processing has been removed.

Log contents of text file before deleting

My script isn't logging the contents of run.txt to log.txt
I've tried to remove the delete command to see if it was deleting it too quickly and therefore couldn't log. But that wasn't the case.
What should I change?
#ECHO OFF &setlocal
SET File=run.txt
type %File%
for /f "tokens=*" %%A in (%File%) do (echo >> log.txt)
del "%File%" /s /f /q > nul
pause
Here is a very simple way to do the task you are requiring.
#echo off
REM Will only grab the first line of the file
set /p file=<run.txt
REM For the last line use a for loop
for /f "tokens=*" %%a in (%file%) do set last_line=%%a
(
echo %file%
)>>log.txt
del /f %file% >nul
If not %errorlevel% equ 0 (
ECHO ERROR - %errorlevel%
pause
exit /b
)
ECHO Success!
timeout /t 003
exit /b %errorlevel%
EXPLANATION
set /p is for set prompt. For more information you can use set /? in your CMD window or check out this site.
I wish I could speak more on what < does, but what it is doing here is piping the content of run.txt to our variable.
Then we echo out our variable to our log file with (ECHO This is our %file%)>>destination
>> is to append where > is to overwrite the file.
(
echo %file%
echo.
)>>%file%
Checking for an error is probably unnecessary, but I believe it is a good habit to build on which is what I am trying to do with that If not %errorlevel% statement.
No error? We Success and timeout ourselves for xxx seconds.
Try:
#ECHO OFF &setlocal
SET "File=run.txt"
type "%File%" >> "log.txt" && (del "%File%" /f > nul)
pause

Batch delete files in variable

I have a batch file which searches through a directory tree deleting generated file backups.
I want to edit the script to run the del command against the files found in the search, but I can't get it to work.
I've searched other threads and set it up similarly but without the expected results.
#echo off
pushd FILEPATH
echo Searching directories...
for /f "delims=" %%G in ('dir /b /s *.0**.rfa') do echo "%%G"
echo.
IF /I "%%G" == "" GOTO NOTFOUND
set /P delete="Delete files? [Y/N]: "
IF /I "%delete%" NEQ "Y" GOTO ENDOF
echo Deleting files...
echo.
del "%%G"
echo.
echo Done!
timeout 5
exit
:ENDOF
echo Aborted.
timeout 5
exit
:NOTFOUND
echo Found nothing.
timeout 5
exit
Result:
Deleting files...
Could Not Find FILEPATH\ %G
Done!
Do you really need the for loop? The following should work exactly as you want:
#echo off
dir /b /s "*.0*.rfa" || echo Found nothing. & goto :finish
choice /m "delete all? "
if errorlevel 2 echo Aborted. & goto :finish
echo Deleting files...
del /q /s "*.0*.rfa"
echo Done.
:finish
timeout 5
exit /b

My batch script doesn't use if command correctly

I've spent a few days trying to get this batch script to work, but it just does not seem to work properly. It seems to just do whatever it wants after it prompts me to set a variable and i set it.
For example, I might enter n when it says that it doesn't seem to exist, and it will just end the script like it should. But if I re-open it, and it says the same thing as before, and I enter n again, it might just jump to :DeleteCalc, as if I typed y.
Here's my script:
#echo off
:Begin
color fc
title My script
cls
if not exist "C:\calc.exe" (
echo calc.exe doesn't seem to exist. Attempt deletion anyway? ^(Y/N^)
set "calcnotexist="
set /p "calcnotexist="
::This command checks to see if the user inputs a quotation mark. If they do, it echos that quotes cannot be inputted.
setlocal EnableDelayedExpansion
if not !calcnotexist!==!calcnotexist:^"=! set "calcnotexist="
endlocal & if "%calcnotexist%"=="" (
echo ERROR - Quotes cannot be entered.
pause
goto Begin
)
if /i "%calcnotexist%"=="Y" (
echo.
goto DeleteCalc
)
if /i "%calcnotexist%"=="Yes" (
echo.
goto DeleteCalc
)
if /i "%calcnotexist%"=="N" goto End
if /i "%calcnotexist%"=="No" goto End
echo ERROR - Unrecognized input
pause
goto Begin
)
:calcDoesExist
title My script
cls
echo calc.exe found. Delete? ^(Y/N^)
set "calcexist="
set /p "calcexist="
::This command checks to see if the user inputs a quotation mark. If they do, it echos that quotes cannot be inputted.
setlocal enabledelayedexpansion
if not !calcexist!==!calcexist:^"=! set "calcexist="
endlocal & if "%calcexist%"=="" (
echo ERROR - Quotes cannot be entered.
pause
goto calcDoesExist
)
if /i "%calcexist%"=="Y" goto DeleteCalc
if /i "%calcexist%"=="Yes" goto DeleteCalc
if /i "%calcexist%"=="N" goto End
if /i "%calcexist%"=="No" goto End
echo ERROR - Unrecognized input
pause
goto calcDoesExist
:DeleteCalc
cls
echo Deleting...
if not exist C:\calc.exe goto Success
del /f /q C:\calc.exe >nul 2>nul
if not exist C:\calc.exe goto Success
echo Fail!
echo.
echo calc.exe could not be deleted.
echo.
pause
goto End
:Success
echo Deleted!
echo.
echo calc.exe successfully deleted.
echo.
pause
goto End
:End
exit /b
What could I possibly be doing wrong?
Thanks
P.S. I tested this by opening CMD and running the batch script multiple times in there. (but it also doesn't work right when just double clicking it)
If you restructure your script there will be no need for the extended If blocks and therefore no necessity to EnableDelayedExpansion. Also if you use Choice you will not have to do all of the verification of responses.
Example:
#Echo Off
Title My script
Color FC
:Begin
If Exist "C:\calc.exe" GoTo calcDoesExist
Echo(calc.exe doesn't seem to exist.
Choice /M "Attempt deletion anyway"
If ErrorLevel 3 (ClS & GoTo Begin)
If ErrorLevel 2 GoTo End
If ErrorLevel 1 GoTo Success
GoTo End
:calcDoesExist
Echo(calc.exe found.
Choice /M "Delete"
If ErrorLevel 3 (ClS & GoTo calcDoesExist)
If ErrorLevel 2 GoTo End
If ErrorLevel 1 GoTo DeleteCalc
GoTo End
:DeleteCalc
ClS
Echo(Deleting...
Del /A /F "C:\calc.exe">Nul 2>&1
If Not Exist "C:\calc.exe" GoTo Success
Echo(Fail!
Echo(
Echo(calc.exe could not be deleted.
GoTo End
:Success
Echo(
Echo(Deleted!
Echo(
Echo(calc.exe does not exist.
:End
Echo(
Echo(Exiting...
Timeout 3 /NoBreak>Nul
Exit /B

How do I exclude something from showing up with FindStr?

I need to find multiple strings but the strings I look up flag for being in the batch itself. I search the string Incognito and the batch including it flags. How do I prevent this?
Edit: This is a snippet of my current code. Basically it opens the text file and shows this batch file in it and other stuff too which is good, but I need it not to flag this batch file.
findstr /i /s /m "Obligatory" *.* > str-unfixed.txt
if %errorlevel%==0 (
Call :TypeWriter "Obligatory Strings Found."
) else (
Call :TypeWriter "No Obligatory Strings Found."
)
start "" "C:\Users\%USERNAME%\Desktop\str-unfixed.txt"
Don't worry about the TypeWriter, this is only a snippet.
Edit2: Thanks for the edit Mofi, but it blanks out at console and doesn't complete.
Full script. Here we go.
#echo off
goto Next
::*************************************************************
:TypeWriter
echo(
(
echo strText=wscript.arguments(0^)
echo intTextLen = Len(strText^)
echo intPause = 30
echo For x = 1 to intTextLen
echo strTempText = Mid(strText,x,1^)
echo WScript.StdOut.Write strTempText
echo WScript.Sleep intPause
echo Next
)>%tmp%\%~n0.vbs
#cscript.EXE /noLogo "%tmp%\%~n0.vbs" "%~1"
echo(
exit /b
::**************************************************************
:Next
#echo off
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
%SystemRoot%\System32\findstr.exe /i /s /m "Vape" *.* | %SystemRoot%\System32\findstr.exe /E /L /V /C:"%~nx0" >"%OutputFile%"
for %%I in ("%OutputFile%") do if %%~zI == 0 goto VapeNoFileFound
for %%I in ("%OutputFile%") do if %%~zI == 1 goto VapeFileFound
:VapeFileFound
Call :TypeWriter "Vape Strings Found."
goto Kurium
:VapeNoFileFound
Call :TypeWriter "No Vape Strings Found."
goto Kurium
:Kurium
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
%SystemRoot%\System32\findstr.exe /i /s /m "Kurium" *.* | %SystemRoot%\System32\findstr.exe /E /L /V /C:"%~nx0" >>"%OutputFile%"
for %%I in ("%OutputFile%") do if %%~zI == 0 goto KuriumNoFileFound
for %%I in ("%OutputFile%") do if %%~zI == 1 goto KuriumFileFound
:KuriumFileFound
Call :TypeWriter "Kurium Strings Found."
goto Spook
:KuriumNoFileFound
Call :TypeWriter "No Kurium Strings Found."
goto Spook
:Spook
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
%SystemRoot%\System32\findstr.exe /i /s /m "Spook" *.* | %SystemRoot%\System32\findstr.exe /E /L /V /C:"%~nx0" >>"%OutputFile%"
for %%I in ("%OutputFile%") do if %%~zI == 0 goto SpookNoFileFound
for %%I in ("%OutputFile%") do if %%~zI == 1 goto SpookFileFound
:SpookFileFound
Call :TypeWriter "Spook Strings Found."
goto Aimassist
:SpookNoFileFound
Call :TypeWriter "No Spook Strings Found."
goto Aimassist
:Aimassist
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
%SystemRoot%\System32\findstr.exe /i /s /m "Aimassist" *.* | %SystemRoot%\System32\findstr.exe /E /L /V /C:"%~nx0" >>"%OutputFile%"
for %%I in ("%OutputFile%") do if %%~zI == 0 goto AANoFileFound
for %%I in ("%OutputFile%") do if %%~zI == 1 goto AAFileFound
:AAFileFound
Call :TypeWriter "Aim Assist Strings Found."
goto Triggerbot
:AANoFileFound
Call :TypeWriter "No Aim Assist Strings Found."
goto Triggerbot
:Triggerbot
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
%SystemRoot%\System32\findstr.exe /i /s /m "Triggerbot" *.* | %SystemRoot%\System32\findstr.exe /E /L /V /C:"%~nx0" >>"%OutputFile%"
for %%I in ("%OutputFile%") do if %%~zI == 0 goto TRNoFileFound
for %%I in ("%OutputFile%") do if %%~zI == 1 goto TRFileFound
cscript //nologo "C:\Users\%USERNAME%\Desktop\dedup.vbs" < "C:\Users\%USERNAME%\Desktop\str-unfixed.txt" > "C:\Users\%USERNAME%\Desktop\str-fixed.txt"
del /s /q "C:\Users\%USERNAME%\Desktop\str-unfixed.txt" > nul
:TRFileFound
Call :TypeWriter "Triggerbot Strings Found."
start "" "C:\Users\%USERNAME%\Desktop\str-fixed.txt"
:TRNoFileFound
Call :TypeWriter "No Triggerbot Strings Found."
start "" "C:\Users\%USERNAME%\Desktop\str-fixed.txt"
pause > nul
::************************************************
And if you need dedup.vbs:
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
Set Dict = CreateObject("Scripting.Dictionary")
Do Until Inp.AtEndOfStream
On Error Resume Next
Line=Inp.readline
Dict.Add Line, ""
Loop
For Each thing in Dict.Keys()
Outp.writeline thing
Next
Edit3: Thanks Mofi!
My problem: need to get the items in the text document to show up on cmd window.
Script:
#echo off
goto Next
::*************************************************************
:TypeWriter
echo(
(
echo strText=wscript.arguments(0^)
echo intTextLen = Len(strText^)
echo intPause = 30
echo For x = 1 to intTextLen
echo strTempText = Mid(strText,x,1^)
echo WScript.StdOut.Write strTempText
echo WScript.Sleep intPause
echo Next
)>%tmp%\%~n0.vbs
#cscript.EXE /noLogo "%tmp%\%~n0.vbs" "%~1"
echo(
exit /b
::**************************************************************
:Next
#echo off
findstr /i /s /m /C:"Vape" /C:"Kurium" /C:"Spook" /C:"Aimassist" /C:"Triggerbot" /C:"Smoothaim" *.* > str-unfixed.txt
cscript //nologo "C:\Users\%USERNAME%\Desktop\dedup.vbs" < "C:\Users\%USERNAME%\Desktop\str-unfixed.txt" > "C:\Users\%USERNAME%\Desktop\str-fixed.txt"
if %errorlevel%==0 (
Call :TypeWriter "Blacklisted Strings Found."
start "" "C:\Users\%USERNAME%\Desktop\str-fixed.txt"
) else (
Call :TypeWriter "No Blacklisted Strings Found."
start "" "C:\Users\%USERNAME%\Desktop\str-fixed.txt"
)
pause > nul
::************************************************
The batch file could be filtered out for example with using this code:
#echo off
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
%SystemRoot%\System32\findstr.exe /I /M /S "Obligatory" *.* | %SystemRoot%\System32\findstr.exe /E /L /V /C:"%~nx0" >"%OutputFile%"
for %%I in ("%OutputFile%") do if %%~zI == 0 goto NoFileFound
call :TypeWriter "Obligatory strings found."
start "" "%OutputFile%"
set "OutputFile="
goto :EOF
:NoFileFound
del "%OutputFile%"
set "OutputFile="
call :TypeWriter "No obligatory string found."
goto :EOF
:TypeWriter
echo %~1
The output of first FINDSTR is filtered with a second FINDSTR which outputs all lines not ending with the name of the batch file searched as case-sensitive literal string.
The FOR command is used to check the file size of the output file.
Is the output file an empty file, i.e. the file size is equal 0 bytes, the string Obligatory was not found in any file except the batch file itself resulting in deleting the output file and printing the appropriate message.
Otherwise after printing the message that the string was found, the output file is opened in the application associated with file extension .txt.
The batch file above was tested for both scenarios on a subdirectory and not on entire drive C: as it can take a quite long time to finish on C:. There are hundred thousands of files on drive C: with dozens of GiB in total to search for the string when using *.* as file name pattern and start in root of drive C:.
EDIT 1: Define string to find in two parts
A much better solution as above is avoiding search string being in batch file. This can be done by using an environment variable for the string to find and define the value of the environment variable in two steps.
#echo off
setlocal
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
set "StringToFind=Obli"
set "StringToFind=%StringToFind%gatory"
%SystemRoot%\System32\findstr.exe /I /M /S "%StringToFind%" *.* >"%OutputFile%"
if errorlevel 1 (
del "%OutputFile%"
call :TypeWriter "No %StringToFind% strings found."
) else (
call :TypeWriter "%StringToFind% strings found."
start "" "%OutputFile%"
)
endlocal
goto :EOF
:TypeWriter
echo %~1
This batch file also searches for Obligatory, but it does not contain this string, just Obli and gatory.
EDIT 2: Define strings to find with omitted escape character
Here is one more solution where the multiple strings to find are assigned to environment variables with escape character ^ anywhere in the middle of the search strings to exclude the batch file.
^ is removed by Windows command interpreter on assigning the search strings to the environment variables as not being found within a double quoted string. Please note that this solution requires that the lines
set SearchX=S^earch String
do not have 1 or more trailing spaces/tabs as the trailing whitespace(s) would be also assigned to the environment variable. The search would not work anymore as expected with a not visible space or horizontal tab at end of those lines as being part of the search string.
Additionally this batch code outputs first each file name found by FINDSTR containing one of the 6 search strings to console window and next redirects the file name into the output text file.
#echo off
setlocal EnableExtensions
set "OutputFile=%USERPROFILE%\Desktop\str-unfixed.txt"
rem Define all search strings with omitted escape character.
set Search1=V^ape
set Search2=K^urium
set Search3=S^pook
set Search4=A^imassist
set Search5=T^riggerbot
set Search6=S^moothaim
rem Delete the output file from a previous run if existing at all.
del "%OutputFile%" 2>nul
for /F "delims=" %%I in ('%SystemRoot%\System32\findstr.exe /I /M /S /C:"%Search1%" /C:"%Search2%" /C:"%Search3%" /C:"%Search4%" /C:"%Search5%" /C:"%Search6%" *') do (
echo %%I
echo %%I>>"%OutputFile%"
)
if exist "%OutputFile%" (
call :TypeWriter "Obligatory strings found."
start "" "%OutputFile%"
) else (
call :TypeWriter "No obligatory string found."
)
endlocal
goto :EOF
:TypeWriter
echo %~1
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
del /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
rem /?
set /?
setlocal /?
start /?
See also the Microsoft support article Testing for a Specific Error Level in Batch Files and Microsoft TechNet article Using command redirection operators.
Just pipe the results through another check for the script name.
Replace your first line, findstr /i /s /m "Obligatory" *.* > str-unfixed.txt with this:
findstr/ism "Obligatory" *.*|findstr/ixvc:"%~nx0">str-unfixed.txt
I will add however that I would strongly suggest not searching through every single file on the C: drive looking for a specific search term. You really do need to filter this somehow perhaps by altering your file wildcard/mask.

Resources