Exclusion of files of certain extension - windows

In a Windows cmd batch script named my.bat, I want to execute a command for all the files in the current directory except for the batch file my.bat.
I use below command in my.bat currently to run the command only for *.txt *.ppt, but really as new files of different extensions might be added to the folder and hence execution of this command by excluding one type of file extension (in my case *.bat) would be more readable/helpful.
FOR /F "delims=|" %%i IN ('dir /b *.txt *.ppt') DO echo %%i
Question is: How do I exclude that file alone with that particular file extension and make the for command execute on all files of all extensions except the excluded one?

FOR /F "tokens=* delims=|" %%i IN ('dir /b *.*') do if not %%~xi==.bat echo %%i
I have added tokens=* in as well otherwise you won't get full filenames if they have spaces.
To echo without the dot
setlocal enabledelayedexpansion
FOR /F "tokens=* delims=|" %%i IN ('dir /b *.*') do (
set e=%%~xi
set e=!e:.=!
echo !e!
)
This is providing that the file doesn't have any other dots, otherwise it will remove them too. This is a bit more sturdy than just removing the 4th character from the end though, as not all files have a 3 character extension.

You could pass the output of the dir /b command through findstr, like so:
FOR /F "delims=|" %%i IN ('dir /b ^| findstr /v /r "^my.bat$"') DO echo %%i
The /v option to findstr prints anything that doesn't match the parameter. The match is based on a regular expression that matches only lines that contain my.bat and nothing else.

Related

Getting Parent Directory for each file from Dir Output

I have a directory with multipe levels of folders.
I am completely new to writing batch files and I am writing my first one.
Stuck for ages on trying to
find all files in the directory including sub-folder
get parent directory for each file
save as variable like %parent.filename%
I have been searching here:
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490909(v=technet.10)
And on Google but unfortunately I am stuck.
So now I managed to save the full path of each file as variable, but I want %Folder.FileName% to return the parent directory only, not the full path.
This is the code I have been testing in the command prompt.
For /F %A in ('Dir Linkedin /A-D /s /b /o') do SET Folder.%~nxA=%~pA
EDIT
I also saw this thread
And tried this code:
FOR /F %A in ('Dir Linkedin /A-D /s /b /o') do ECHO %~nxA %~pA >>Paths.txt
FOR /F "tokens=1,2" %A in (Paths.txt) do SET Parent.%A=%~nB
But %~nxB doesn't return any value... I expected it to get the last string of the path.
FOR /F %A in ('Dir Linkedin /A-D /s /b /o') do ECHO %~nxA %~pA. >>Paths.txt
FOR /F "tokens=1,2" %A in (Paths.txt) do SET Parent.%A=%~nB
Note the extra .
The path provided by the ~p modifier terminates in \ so adding . to this means "the directory name itself as though it was a filename"
As a one-line command (within a batch, decorated by standard palaver)
#ECHO OFF
SETLOCAL
FOR /F %%A in ('Dir test* /A-D /s /b /o') do FOR /F %%S in ("%%~pA.") do SET Parent.%%~nxA=%%~nS
set parent.
GOTO :EOF
I used the filemask test* to better suit my system.
I can't imagine you'd voluntarily perpetually re-type the command, so the format for use within a batch file is shown.
I would suggest you do this as a single nested For loop from the Command Prompt and with no output file:
For /F "Delims=" %A In ('Dir /B/S/A-D "Linkedin" 2^>NUL')Do #For %B In ("%~pA.")Do #Set "Folder.%~nxA=%~nxB"
From a batch-file, perhaps this would help you out:
#Echo Off
Rem Remove any existing Folder. variables
For /F "Tokens=1*Delims==" %%A In ('Set Folder. 2^>NUL')Do Set "%%A="
Rem Set the new variables
For /F "Delims=" %%A In ('Dir /B/S/A-D "Linkedin" 2^>NUL')Do For %%B In ("%%~pA.")Do Set "Folder.%%~nxA=%%~nxB"
Rem View any returned variables
Set Folder. 2>NUL&&Pause

Batch file to count file types in sub directories

I need a batch file that counts certain file types in sub directories. In this case it's .txt and .xls files. At the end of the file it reports this back.
#echo off
REM get script directory
set scriptdir=%~dp0
REM change directory to script directory
cd /d %scriptdir%
setlocal
set txtcount=0
set xlscount=0
for %%x in ('dir *.txt /s ) do set /a txtcount+=1
for %%x in ('dir *.xls /s ) do set /a xlscount+=1
echo %txtcount% text files
echo %xlscount% .xls files
endlocal
pause
My batch file doesn't report back the correct count of files. I thought it might be continually counting but I've set the count variables to local so I'm not sure what's up.
There's three problems with your script:
You want to iterate over command output, so you need FOR /F
You're not using the "bare" /B format, i.e. DIR outputs more than just filenames
You're missing the closing single quote twice
Replace your loops with this:
FOR /F %%X IN ('DIR /S /B *.txt') DO SET /A "txtcount+=1"
FOR /F %%X IN ('DIR /S /B *.xls') DO SET /A "xlscount+=1"
You are very close, but you are missing the switch /B of the dir command, so the output contains a header and a footer, which are both included in the count. Therefore, change dir *.txt /s to dir *.txt /s /b (same for *.xls) and the count is going to be correct.
Besides that, there are typos: the closing ' is missing -- for %%x in ('dir *.txt /s') do .... In addition, the /F switch at for is missing, which is needed to capture the output of a command. (I assume these things are present in the true script as you would receive errors otherwise.)
Alternative Approach
To count the number of files, you could also do the following:
for /F "delims=" %%X in ('dir /B /S "*.txt" ^| find /C /V ""') do set "COUNT=%%X"
find /V "" searches for non-empty lines, hence all lines returned by dir /B /S are considered as matches; the /C switch simply lets find return the total amount of matching lines.

Truncate filename after a multiple of a special character in windows batch script?

I want to remove the part of a filename after the third "_" from thousand of files. The structure after the third "_" varies and contains "_" in some cases. The length of the first part varies so I can't just remove the first 15 characters. The result should be unique.
The filenames look like this:
00_TEXT_=Text00._AA1234L_AA1_1.pdf
00_TEX_=Text00._AA1234L_AA1_2.pdf
00_TEXT_=TextText00._DD2023A.pdf
00_TEXT_=Text00._AA2345L_BB1_1.pdf
00_TEXT_=Text00._AA2345L_BB1_2.pdf
The result should look like this:
AA1234L_AA1_1.pdf
AA1234L_AA1_2.pdf
DD2023A.pdf
AA2345L_BB1_1.pdf
AA2345L_BB1_2.pdf
Any idea why this is not working:
#echo off
setlocal enabledelayedexpansion
set deletestring=*_*_*_
for /f "delims==" %%F in ('dir /b ^| find "%deletestring%"') do (
set oldfilename=%%F
set newfilename=!oldfilename:%deletestring%=!
Ren "!oldfilename!" "!newfilename!"
)
I was able to get it working with this:
#echo off
setlocal enabledelayedexpansion
set deletestring=*_*_*_*
for /f "tokens=1,2,3,* delims=_" %%F in ('dir /b "%deletestring%"') do (
Ren "%%F_%%G_%%H_%%I" "%%I"
)
endlocal
Note that enabledelayedexpansion isn't really needed in the above.
Alternately, you could do this as a single line (no batch file needed):
for /f "tokens=1,2,3,* delims=_" %F in ('dir /b "*_*_*_*"') do Ren "%F_%G_%H_%I" "%I"
The idea is to simply split the matching filenames apart by underscores and then reconstruct the names during the rename process (%%F_%%G_%%H_%%I gives the original file name when going through the loop). Then rename the file to everything after the 3rd underscore, which is the %%I value.
Your FINDSTR search is wrong - a string of any characters (wildcard) is .*, not *.
Variable find/replace does not support wildcards, except for the !var:*search=! syntax that replaces everthing up until the first occurrence of "search".
There is no need for FINDSTR, all you need is DIR with normal wildcard masking.
You can use FOR /F to parse the name into tokens. I use two loops - the first to get the entire name, and the second to parse out the portion after the 3rd _.
The following should work:
#echo off
for /f "eol=: delims=" %%A in (
'dir /b /a-d *_*_*_*'
) do for /f "tokens=3* delims=_" %%B in ("%%A") do ren "%%A" "%%C"
Or you could use my jren.bat utility that renames files using regular expression replacement. It is a hybrid JScript/batch script that runs natively on any Windows machine from XP onward.
jren "^(.*?_){3}" ""
Use CALL JREN if you put the command within another batch script.

How to deal with an em dash in a filename

On a PC with Windows 7, I'm using a simple batch script to rename some Excel files, pre-pending their parent folder name:
for /f "delims=" %%i in ('dir /b /AD') do (
cd "%%i"
for /f "delims=" %%j in ('dir /b *.xl*') do ren "%%~j" "%%i_%%~j"
cd..
)
I noticed that some files generated an error, "System cannot find the specified file." These files all had an em dash (—) in the filename. After I changed the em dash to a regular hyphen (-), using Windows Explorer, the script worked fine on these files.
How can I help script the rename of these files?
Your problem is not with the batch variables: from the command line this works fine:
for %i in (*) do ren "%~i" "test_%~i"
but, as can be seen from:
for /f "delims=" %i in ('dir /b /a-d') do #echo ren "%~i" "test2_%~i"
dir /b is changing the em dash to a hyphen, and so the ren command clearly won't find the file to change.
For your examples you should find:
for /d %%i in (*) do (
and
for %%j in (*.xl*) do ...
should work fine.
If you need the dir /b for other reasons, I don't see a solution right now.
(I had a convoluted attempt exchanging all hyphens for question marks, using the "Environment variable substitution" and "delayed environment variable expansion" as described in SET /? and CMD /?, allowing any character to match, and then again use ren pattern matching to ignore the problem.
I.e.
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "delims=" %%I in ('dir /b /a-d') do (
Set K=%%I
ren "!K:-=?!" "test2_!K:-=?!"
)
but ren * x* replaces the start of the files with x, so the above replaces the hyphens with the content at that location before test_ was inserted.
So the best this approach can do is convert the em dashes to hyphens with:
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "delims=" %%I in ('dir /b /a-d') do (
Set K=%%I
ren "!K:-=?!" "test2_!K!"
)
)
And confirming it is the output of dir /b that is the problem: on the command line:
dir /b *—* > test.txt
where that — is an em dash, will only list the files with em dashes, but, in the output file, e.g. Notepad test.txt, you'll only find hyphens, and no em dashes.
BTW I've done all this testing on Windows 8.1 which VER displays as Microsoft Windows [Version 6.3.9600].
(As I mention above I did have ren * x* in this answer, but that replaces the first character with x rather than insert it, which I always thought ren did!)

batch script delete file containining certain chars

I have almost no experience in batch, but now I need a script to delete all files that contain certain characters in their names from a folder and its subfolders on Windows 64. I only did simple things in batch like
del "C:\TEST\TEST2\*.TXT"
But I have no idea how to perform the filtering I need.
Could someone help me to achieve this using batch?
EDIT more exactly, the question is "how to tell batch to include subfolders?"
The /s switch exists on quite a few commands (including del)
del /s "C:\TEST\TEST2\*.TXT"
The help for del /? says:
/S Delete specified files from all subdirectories.
Try this:
#echo off & setlocal
set "MySearchString=X"
for /f "delims=" %%i in ('dir /b /s /a-d ^| findstr /i "%MySearchString%"') do echo del "%%~i"
Set the variable MySearchString to the character or string to search and remove the echo command, if the output is OK.
You can also specify the MySearchString for the file name only:
#echo off & setlocal
set "MySearchString=T"
for /r %%a in (*) do for /f "delims=" %%i in ('echo("%%~na" ^| findstr /i "%MySearchString%"') do echo del "%%~fa"

Resources