I am making a simple program to list all the files in a certain folder and I want to remove all files (from the text file or wherever is more efficient) that don't have extensions.
This is my current code:
dir /s/b *.* > E:/Project.sav
for /f "Delims=" %%A in (E:/Project.sav) do (
echo %%A
)
and I get a mix of files like this:
C:\Users\User\Desktop\TEst\05f429069e65dwqewqeqweqeq0a3f294cc3128ab
C:\Users\User\Desktop\TEst\063bf0fui3ucinyh3ruincuiwhwu3gssssybwyrbweib
C:\Users\User\Desktop\TEst\hs_err_pid3080.log
C:\Users\User\Desktop\TEst\hs_err_pid5220.log
If you don't need the intermediate file, then all you need is the DIR command:
dir /s /b *.
Note that the above will include directory names as well as file names, as does your original code. If you only want files, then add the /A-D option:
dir /s /b /a-d *.
If you need the complete listing in E:/Project.sav, then you can use FINDSTR with a regular expression to filter out the entries that contain an extension:
findstr /vr "\.[^\\]*$" "E:/Project.sav"
if "%%~xA" neq "" echo %%A
should do what you want.
If "the extension of the filename in %%A" is not equal to "" echo....
Related
I'm new to batch scripting and trying to find a way to iterate through all files in a folder and print the names of all files who start with Test_ and end with .py (i.e python files)
I'm stuck here:
#echo off
for /r %%f in (*) do (
echo %%f | findstr /r "^Test_[.]*\.py$"
)
pause
But this doesn't echo anything to screen.
Can you help?
Thanks,
Noam
Try "Dir /b "Test_*.py""
Also you can do "Dir /b "C:\path\Test_*.py""
You may find the Where command useful:
Where/R . "Test_?*.py"
I have files with the following syntax:
LWD_???_??????_???_??_??_LP?_??_?_*.PDF
Example:
LWD_ARC_G10000_102_UE_XX_LP5_08_E_Uebersicht_Bodenplatten
I want to extract substrings out of the file name and put the file into a folder with the path based on that file name like this:
C:\Lp5\ARC\G10\
First folder is the 7th part of the file name, the 2nd part is the second folder and the first 3 chars of the 3rd part is the last folder.
Then in addition to that I need an extra delete: When the files are copied to the specific folder there is a consecutively numbered part in the file name. I need the "older" files deleted so that only the "last" file is in this folder. The numbers/index is always the 30th and the 31st char.
LWD_FEU_L20000_005_IZ_00_LP8_XX_F.pdf Index 00
LWD_FEU_L20000_005_IZ_00_LP8_01_F.pdf Index 01
For now I only have a batch with static folders:
FOR /R "E:\Downloads" %%i in (LWD_ELT_A10?00_???_??_??_LP5*) do move "%%i" "C:\Lp5\ELT\A10"
FOR /R "E:\Downloads" %%i in (LWD_???_A10000_???_??_??_LP5*) do del "%%i"
...
Does anyone have an idea how to do that without VBS or sth. like that - only Windows Batch or PowerShell?
My batch strategy is as follows:
1) get list of PDF files using DIR /B
2) parse each file name into a string consisting of (pipe delimited)
file mask that matches name with ?? wildcard for positions 30,31
destination path
full file name
3) sort the strings descending, resulting in the most recent version at the top of each file name grouping.
4) process the output with FOR /F, parsing out the file mask, destination path, and full name
5) for each iteration, create the destination folder if it does not already exist, and then conditionally copy the file to the destination if there does not yet exist a file that matches the file mask.
The above strategy is non-destructive, as the original files all remain in place. You could modify step 5 to be destructive - move the newest files instead of copy, and delete the rest.
You could implement the above strategy fairly easily with pure batch. But I would use my REPL.BAT utility - a hybrid JScript/batch script that can efficiently perform sophisticated regular expression replacements. JREPL.BAT is pure script that runs natively on any Windows machine from XP onward.
The following are untested
Non-destructive version
#echo off
for /f "tokens=1,2,3 delims=|" %%A in (
'dir /b /a-d LWD_*.PDF ^| jrepl "^(LWD_(...)_(...)..._..._.._.._(LP.)_)..(_._.*\.PDF)$" "$1??$5|c:\$4\$2\$3|$&" /i /a ^| sort /r'
) do (
md "%%B" >nul 2>nul
if not exist "%%B\%%A" copy "%%C" "%%B" >nul
)
Destructive version
#echo off
for /f "tokens=1,2,3 delims=|" %%A in (
'dir /b /a-d LWD_*.PDF ^| jrepl "^(LWD_(...)_(...)..._..._.._.._(LP.)_)..(_._.*\.PDF)$" "$1??$5|c:\$4\$2\$3|$&" /i /a ^| sort /r'
) do (
md "%%B" >nul 2>nul
if not exist "%%B\%%A" (move "%%C" "%%B" >nul) else del "%%C"
)
#echo off
set out=%~dp0\FileName.txt
(for /r %~dp0 %%F in ((*System1*.txt*) | (*System2*.txt*)) do (if %%~zF GEQ 1 echo %%F)) > %out%
exit /b
I am trying with the above batch file to look at the directory the batch file is in for files containing a certain string and there size is over 0KB.
The problem I am having is with the OR statement.
The Batch file below fulfills your specifications:
#echo off
set out=%~dp0\FileName.txt
rem "am trying with this batch file to look at the directory the batch file is in"
(for /r "%~dp0" %%F in (*System1*.txt* *System2*.txt*) do (
rem "I want all files greater than 0kb to be written out"
if %%~zF GEQ 1 (
rem "Is there a way to just exclude this Filename.txt file?"
if "%%~nxF" neq "Filename.txt" echo %%F
)
)) > "%out%"
exit /b
However, you must note the following points:
The path to the batch file (%~dp0) should be enclosed in quotes in case it may include spaces.
If there are no other files with System, just the desired System1 or System2, then (*System*.txt*) wild-card would be enough.
Usually all files have a size greater than zero bytes. If your system does not regularly create empty files, the related if command is not necessary.
The output filename Filename.txt will never match the given *System*.txt* wild-card, so the last if command is not necessary.
Without further details this is a possible solution using your code as a base:
#echo off
set "out=%~dp0\FileName.txt"
(for /r "%~dp0" %%F in (*System*.txt*) do if %%~zF GTR 0 echo %%F)>"%out%"
exit /b
#echo off
set "out=%~dp0FileName.txt"
(for /r "%~dp0" %%F in (*System1*.txt* *System2*.txt*) do if %%~zF GEQ 1 echo %%F) > %out%
exit /b
for command allow multiple sets of files in the in clause, so, just include them.
I'm looking for way to rename multiple files with a batch job.
Yes, I know there are many Applications around which can achieve this.
But I need an automated way, something like a Batch File which I can call from a Scheduler (SOS Job Scheduler). We need to rename hundreds of files daily!
The Goal is to set the 17-25 charcaters at the beginning of the file.
00010028229720270014468393_TB-E.pdf -> 00144683930001002822972027_TB-E.pdf
000100282297202700144683931ESR-AF.pdf -> 001446839300010028229720271ESR-AF.pdf
00010031141040250016353371ESR-AF.pdf -> 00163533700010031141040251ESR-AF.pdf
0001003167580004001667217KTO.pdf -> 0016672170001003167580004KTO.pdf
Here an example which is more clearer:
0001 002822972 027 001446839 _TB-E .pdf -> 001446839 0001 002822972 027 _TB-E .pdf
#ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*" '
) DO (
SET "name=%%a"
CALL :transform
)
GOTO :EOF
:transform
ECHO REN "%sourcedir%\%name%" "%name:~16,9%%name:~0,16%%name:~25%"
GOTO :eof
The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.
Note that the very first example you've presented has ...393_TB-E... in the transformed version, that 3 is missing.
This can be accomplished very simply with the help of REPL.BAT - a hybrid JScript/batch utility that performs a regex search and replace on each line from stdin and writes the result to stdout. The utility uses only native scripting capabilities that are available to any modern Windows machine from XP onward; no 3rd party executable required. Complete documentation is embedded within the script.
Assuming REPL.BAT is somewhere within your PATH:
#echo off
pushd "c:\sourcePath"
for /f "delims=" %%A in (
'dir /b /a-d *.pdf ^| repl "(.{16})(.{9}).*" "ren \q$&\q \q$2$1*\q" x'
) do %%A
popd
Using only native batch commands, without any CALL:
#echo off
setlocal disableDelayedExpansion
pushd "c:\sourcePath"
for /f "delims=" %%F in ('dir /b /a-d *.pdf') do (
set "file=%%F"
setlocal enableDelayedExpansion
ren "!file!" "!file:~16,9!!file:~0,17!*"
endlocal
)
popd
If you know that none of your file names contain the ! character, then you can simply enable delayed expansion at the top, and remove both SETLOCAL and ENDLOCAL from within the loop.
Both solutions above rely on the fact that * at the end of the target name will preserve the remainder of the original file name. See How does the Windows RENAME command interpret wildcards? for more info.
(\d{16})(\d+)(.*?\.pdf) -> \2\1\3
{16} means you take 16 repetitions (of a digit)
Probably far too easy question, but how do I match a file extension such as .jpg while not matching jpg~ (i.e. a jpg that a program has made a local copy of?) My current line is:
for /f %%a in ('dir /b *.jpg') do echo %%~na
But if any program has a copy of one of the files open (and thus has made a .jpg~ file) this regexp will match those too. I found a reference to $ being the 'end of line', but doing this doesn't work at all:
for /f %%a in ('dir /b *.jpg$') do echo %%~na
I don't think it is possible to filter this with just a FOR command (unless you pipe the output of dir to findstr) but in this case, adding a simple if test is all that is needed:
for %%A IN (*.jpg) DO if "%%~xA"==".jpg" #echo %%~A
I think, the problem arises from the short-name representation. (Use dir /X and you can see that xxx.jpg and xxx.jpg~ both have a 8.3 file-name that ends with .jpg.)