BATCH: Delete parts of filename using substring not working - windows

I have several .csv files in one folder. They are saved automatically but with spaces and execution date and time (in seconds) with amount of containing lines.
So far I was not able to run my powershell script with files containing spaces. So I tried to rename filenames using batch. so far nothing is working fine. Either in cmd-line or with a batch file.
Trying to loop in folder to find .csv is working but defining a string and then substring parts of the file not.
for %%i in ('dir *.csv /b /s') do set string = %%~ni
set substr=!string:~20,25!
echo !substr!
I tried first to use % instead of ! but didn't worked as well. Tried to use pipes for the loop as well, didn't worked.
So far my output is just
!string:~20,25!
My output has to be just the "real" filename of the report without anything else before or after it.
For example, do with that path and filename
C:\Users\Username\CSV_Files\Reportoutput Report_2017 2018-01-09T07_10_33.1924R.csv
this
C:\Users\Username\CSV_Files\Report_2017.csv
When I'm able to extract just the filename without any spaces or leading chars like "Reportoutput" (which is always the same) or starting time of report or containing lines in the report I could use that string and combine it with the path where files are saved.
Any ideas? Why is my "substring" not working at all? Do I miss some action? Some code?
I'm using windows.

Based on the file name structure you've presented and looping in one folder, (the current directory), as stated and used in your example code:
#Echo Off
For %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
If you wanted to check inside subfolders of the currect directory then change it to this:
#Echo Off
For /R %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
…and if you want to specify the base directory name then you can do so like the following two examples which use %UserProfile% for demonstration purposes, (change as appropriate).
#Echo Off
For /R "%UserProfile%" %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
and:
#Echo Off
CD /D "%UserProfile%" 2>Nul||Exit /B
For /R %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
Instead of splitting the names using character numbers, this simply takes the second token of the file name string delimited by spaces and adds the original file extension to it in a rename command.

Related

Batch rename multiple files with hyphenated names

I have a series of files that I download/process regularly and need to use a batch file to rename. Each filename is something like word-word-word-datetime.csv. There is always a '-' between words and always -datetime before the '.csv' file extension. I need to remove the -datetime so that the files are named word-word-word.csv. In some cases there might be just one word before the -datetime but there can be a string of many words as well. I download these files and move them to a specific folder for processing, and there is already a batch file in the folder that I need to modify to also rename the files.
For example, I need the filenames below:
this-is-a-file-20200804134809.csv
another-file-20200804134750.csv
some-other-file-20200804134699.csv
file-20200804134389.csv
To be renamed to:
this-is-a-file.csv
another-file.csv
some-other-file.csv
file.csv
This answer is almost exactly what I need, but I'm not familiar enough with the syntax to modify it for renaming files with multiple hyphenated words (code from linked answer copied below).
#echo off
for /F "tokens=1,* delims=-" %%a in ('dir /A-D /B "*.mp4"') do (
echo move "%%a-%%b" "%%a%%~xb"
)
I was able to rename all of the .csv files in my folder, truncating the name to remove the last 15 characters as suggested by #Compo.
#echo off
setlocal enabledelayedexpansion
for %%f in (*.csv) do if %%f neq %~nx0 (
set "filename=%%~nf"
ren "%%f" "!filename:~0,-15!%%~xf"
)
Here's a more robust example, using the advice I provided in the comments:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For /F "EOL=| Delims=" %%G In ('Dir /B /A-D *-??????????????.csv ^
^|"%__AppDir__%findstr.exe" /IR ^
"\-19[0123456789]*\.csv$ \-20[0123456789]*\.csv$"') Do (
Set "BaseName=%%~nG"
SetLocal EnableDelayedExpansion
Ren "%%G" "!BaseName:~,-15!%%~xG"
EndLocal
)

List all files with 2 timestamps, size, but without path or dir

Windows, Command Prompt, need to generate a .txt file output containing of all files from a big and complex dir tree with one (1) line for each files as:
CreationDateYYYYMMDD-HHMMSS, LastModifiedYYYYMMDD-HHMMSS, filesize[no K commas], filename.ext
for example:
20100101-174503, 20120202-191536, 1589567, myfile.ext
The list should not contain lines of dir name entries, etc., only filenames, even if the same file is present in more than once. Time in 24 hours format.
dir /s/t:c/t:w/-c > filelist.txt
command does not exactly works this way.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=c:\program files"
FOR /f "delims=" %%a IN (
'dir /s /b /a-d "%sourcedir%\*" '
) DO (
FOR %%d IN (timewritten timecreated) DO SET "%%d="
FOR %%k IN (-d s h) DO (
IF NOT DEFINED timewritten FOR /f "tokens=1,2 delims= " %%d IN ('dir /tw %%~k "%%a" 2^>nul ^|find "%%~nxa"') DO SET "timewritten=%%d %%e"
IF NOT DEFINED timecreated FOR /f "tokens=1,2 delims= " %%d IN ('dir /tc %%~k "%%a" 2^>nul ^|find "%%~nxa"') DO SET "timecreated=%%d %%e"
)
ECHO !timecreated! !timewritten! %%~za %%~nxa
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
Interesting problem. This code processes it by
First, applying the standard directory-list for filenames on the tree from the relative root (%sourcedir%) to %%a
Using the full filename in %%a, set timewritten and timecreated from an ordinary dir list targeting the file in question.
It appeared that %%~ta didn't play nicely to extract the timestamp for hidden and system files, so I decided to build them from the ordinary dir listing with the appropriate t setting, specifically listing with /a-d, /as and /ah and filtering for the line which matched the filename, which seemed to extract the data appropriately.
I left the date/time in raw format. It should be an easy task to extract the various elements and construct the report in the format you want.
This question is a dupe of the SO post cmd dir /b/s plus date, but posting what worked for me:
#echo off
REM list files with timestamp
REM Filename first then timestamp
for /R %I in (*.*) do #echo %~dpnxI %~tI
#echo off
REM list files with timestamp
REM Timestamp first then name
for /R %I in (*.*) do #echo %~tI %~dpnxI
The above are the versions that you would directly paste into a command prompt.
If you want to use these in a batch file and log the output, you could do something like:
rem: Place the following in a batch file such as DirectoriesBareWithTS.cmd.
rem: As the first step in the batch file, net use to the directory or share you want the listing of
rem: Change to your target directory
Y:
for /R %%I in (*.mp4) do #echo %%~tI %%~dpnxI
Then you can pipe the output to a log file when you execute:
DirectoriesBareWithTS.cmd > C:\temp\GiantLongDirListing.log
You could then import that log into Excel.

Copying files with name containing just numbers using a batchfile

I have a Directory with a deep Directory->Sub-directory tree structure. I need to write a batch file to copy all the numbered files (files with names as digits and no alphabetic characters) from all the sub-directories.
For example, a sub-directory might contain the following files:
WR10091.txt
AX10091.htm
10091.txt
AX10091.xml
10091.xml
I need to copy 10091.txt and 10091.xml to another location. I can copy files like AX10091.xml and AX10091.htm by specifying AX*.*. But I cannot figure out how to copy just numbered files with no alphabetic characters. There are thousands of directories and the directory structure does not have any pattern (the depth of a tree branch can vary considerably).
Any help will be appreciated.
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=%cd%"
set "target=x:\target\folder"
for /r "%source%" %%a in (*) do (
(for /f "delims=0123456789" %%b in ("%%~na") do (
break
)) || echo copy "%%~fa" "%target%"
)
In this code the for %%a will iterate over all the files under the indicated folder. For each of them, the for /f %%b will try to tokenize the file name (%%~na) using numbers as delimiters. If the file name only contains numbers, there will be nothing to process (only delimiters) and the inner for raises errorlevel. This is checked with conditional execution (the code after the || is executed if the previous command fails) and if errorlevel was raised the copy operation is echoed to console.
If the output is correct, remove the echo to perform the copy.
note: the break in the inner for loop is included just to have a command that does nothing when files with non numeric names are found.
#echo off
for /f "tokens=* delims=" %%a in ('dir /b /s /a:-d "*"') do (
echo %%~na|findstr /e /b /r "[1-9]*" >nul 2>nul && (
copy %%~fa c:\somewhere\
)
)
should be executed in the same directory as the files.
for /f "delims=" %%a in ('dir /b/s/a-d ^| findstr /reic:"\\[0-9][0-9]*\..*" /c:"\\[0-9][0-9]*"') do copy "%%~a" "targetDir"
This might not work with XP and/or Vista, but this can be fixed if needed (see What are the undocumented features and limitations of the Windows FINDSTR command).

Trim Date from file name windows script

How do you trim the date from a text file. For example, I have multiple files like:
test_MX_abc_20091011.txt
test_MX_pqrdhdsu_20091011.txt
test_MX_xyieuz_20091011.txt
All files will have test_MX in common but the 3rd part will of different size.
I would like to change into:
test_MX_abc.txt
test_MX_pqrdhdsu.txt
test_MX_xyieuz.txt
I know how to change the file if name is like test_20091011.txt with the below code, But if name has more string along with date, how to do that?
for /F "tokens=1 delims=_" %%i in ("%%~na") do (
move /Y %%~fa %data_in%\%%i%%~xa >nul
)
Thanks in advance.
This rename operation can be done for example with:
#echo off
for /F "tokens=1-3* delims=_" %%A in ('dir /A-D /B test_MX_*.txt') do (
ren "%%A_%%B_%%C_%%D" "%%A_%%B_%%C.txt"
)
Each file name is separated into 4 strings assigned to loop variables A to D with using underscore as separator. The loop variable D takes everything of file name after third underscore.
Or also working for the 3 files:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%F in ('dir /A-D /B test_MX_*.txt') do (
set "ActFileName=%%~nF"
set "NewFileName=!ActFileName:~0,-9!"
ren "%%~F" "!NewFileName!.txt"
)
endlocal
This solution assigns the name of a file without file extension and path to environment variable ActFileName. Next a new environment variable with name NewFileName is defined with name of active file without the last 9 characters (underscore and date string). This modified file name is used next in the rename operation.
Other solutions using commands for, set and ren can be found on Stack Overflow.
Search with the string
[batch-file] for set rename files
and more than 600 results are presented all using more or less something like above.
For details on the used commands, open a command prompt window, execute one after the other following commands and read output help.
dir /?
for /?
ren /?
set /?

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.

Resources