Batch rename: skipping already renamed files - windows

so in one other recent question i needed to find a solution to bulk renaming files by adding .ab into the filename. I succeeded in doing that, but now i face a different problem. Every time i run the batch file, it appends .ab to all the files even those, already renamed. I tried fixing the problem in the following way, which doesn't work.
rem #echo off
FOR /R "C:\Users\" %%G in (*.txt) DO (
%%G|findstr /i /L ".ab">nul
IF errorlevel 1 (
REN "%%G" "%%~nG.ab.txt"
) ELSE (
skip %%G
)
)
pause
Essentially i need to check if the file name already contains ".ab" in its name and then either skip or add .ab depending on the result. I would appreciate any help.

Use a For /F loop, instead of For /R. In addition, instead of using the Dir command with its /S option, (which will output items ending with .txt*), use Where with its /R option instead, (which will output items ending with .txt).
Single line batch-file example, (excludes those basenames ending with, not containing, .ab):
#For /F "Delims=" %%G In ('^""%__AppDir__%where.exe" /R "C:\Users" "*.txt" 2^>NUL^|"%__AppDir__%findstr.exe" /IV "\.ab\.txt$"^"')Do #Ren "%%G" "%%~nG.ab%%~xG"
Don't forget to change C:\Users and/or both instances of .txt and ab as/if necessary.

Related

BATCH Find string in subfolders and move to new location

I'm currently trying to find a string in multiple files.... for example 'Apple' once found i would like to move the files which contain 'Apple' to a new folder.
This is my current script:
findstr /s /m /l /c:"Apple" "C:\Users\User\Desktop\created\*.php"
This finds all of the .php pages which includes the word 'Apple', however it currently lists them, i can't seem to move them into a new location.
I understand i will need to delete "/m" as this prints the file names...
So how do i move them into a new folder?
Thank you
put a for loop around:
for /f "delims=" %%a in ('findstr /smlc:"Apple" "C:\Users\User\Desktop\created\*.php"') do ECHO move "%%~fa" "Z:\New Location\"
Note: this is batch file syntax. For use directly on command line, replace every %% with a single %.
This just echoes the move commands. After troubleshooting, remove the ECHO to arm the move command.
A slightly different alternative, (creates as required a new directory named as the search word, to move it into, and only moves if the file does not already exist in there):
#Echo Off
Set "strPath=%UserProfile%\Desktop\created"
Set "strExtn=.php"
Set "strWord=Apple"
Set "strDest=%UserProfile%\Desktop\test"
CD /D "%strPath%" 2>Nul || Exit /B
For /F "Delims=" %%A In (
'Findstr /MISC:"%strWord%" "%strPath%\*%strExtn%" 2^>Nul'
) Do RoboCopy "%%~dpA." "%strDest%\%strWord%" "%%~nxA" /MOV>Nul
Just modify the values of the variables, lines 2-5, as necessary.

BATCH: Delete parts of filename using substring not working

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.

Change extension of files in windows batch

I am trying to rename a lot of files. I only want to change the extention from ".pdf.OCR.pdf" to ".pdf"
So far I got the following code
rem for /r myPDFfolder %%i in (*.pdf.OCR.pdf) do ren "%%i" "%%~ni.pdf"
But it does not appear to work with the extension that has multiple dots -- what am I doing wrong?
Extension is the part of file name after the last dot.
Use string replacement to strip the unneeded part:
setlocal enableDelayedExpansion
for /f "eol=* delims=" %%i in ('dir /s /b "r:\*.pdf.OCR.pdf"') do (
set "name=%%~nxi"
ren "%%i" "!name:.pdf.OCR=!"
)
P.S. Parsing of dir is used to make the code more robust in case a different text is stripped which might have changed the sorting order and cause for to process the file twice or more times.
There is no need for a batch file. A moderate length one liner from the command prompt can do the trick.
If you know for a fact that all files that match *.pdf.ocr.pdf have this exact case: .pdf.OCR.pdf, then you can use the following from the command line:
for /r "myPDFfolder" %F in (.) do #ren "%F\*.pdf.ocr.pdf" *O&ren "%F\*.pdf.o" *f
The first rename removes the trailing .pdf, and the second removes the .OCR. The above works because *O in the target mask preserves everything in the original file name through the last occurrence of upper-case O, and *f preserves through the last occurrence of lower-case f. Note that the characters in the source mask are not case sensitive. You can read more about how this works at How does the Windows RENAME command interpret wildcards?
If the case of .pdf.ocr.pdf can vary, then the above will fail miserably. But there is still a one liner that works from the command line:
for /r "myPDFfolder" %F in (*.pdf.ocr.pdf) do #for %G in ("%~nF") do #ren "%F" "%~nG"
%~nF lops off the last .pdf, and %~nG lops off the .OCR, which leaves the desired extension of .pdf.
You should not have to worry about a file being renamed twice because the result after the rename will not match *.pdf.ocr.pdf unless the original file looked like *.pdf.ocr.pdf.ocr.pdf.
If you think you might want to frequently rename files with complex patterns in the future, then you should look into JREN.BAT - a regular expression renaming utility. It is pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward. Full documentation is embedded within the script.
Assuming JREPL.BAT is in a folder that is listed within your PATH, then the following simple command will work from the command line, only renaming files that match the case in the search string:
jren "(\.pdf)\.OCR\.pdf$" $1 /s /p "myPDFfolder"
If you want to ignore case when matching, but want to force the extension to be lower case, then:
jren "\.pdf\.ocr\.pdf$" ".pdf" /i /s /p "myPDFfolder"
Alternative solution, without delayed expansion (remove ECHO to actually rename any files):
#echo off
rem iterate over all matching files:
for /F "delims=" %%A in (
'dir /S /B /A:-D "myPDFfolder\*.pdf.OCR.pdf"'
) do (
rem "%%~nA" removes last ".pdf"
for /F %%B in ("%%~nA") do (
rem "%%~nB" removes ".OCR" part
for /F %%C in ("%%~nB") do (
rem "%%~nC" removes remaining ".pdf"
ECHO ren "%%~fA" "%%~nC.pdf"
) & rem next %%C
) & rem next %%B
) & rem next %%A
NOTE: The directory tree is enumerated before for iterates through it because otherwise, some items might be skipped or tried to be renamed twice (see this post concerning that issue).

Batch file that looks for a folder that contains 1 file

i have a lot of folders with a random number of files within.
And the most of them just have 1 file inside it, these files needs to move to the parent folder. but i don't know how i should do it with a batch file.
I use Windows 7 Ultimate
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
FOR /d /r "%sourcedir%" %%a IN (*) DO (
FOR /f %%c IN ('dir /b/a-d "%%a\*.*" 2^>nul ^|find /c /v ""') DO IF %%c==1 ECHO(MOVE "%%a\*.*" "%%a\..\"
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The for /d /r finds all of the subdirectory names starting at sourcedir and assigns thenm to %%a in turn.
Each directory is then examined for filenames only; the 2>nul suppresses error messages for empty directories, and the output of the dir command is fed to find which counts (/c) the number of lines which don't match "" (ie. counts the lines of directory = # files returned). This is applied to %%c
If %%c is 1, then move all (one) files from the directory to its parent.
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
This solution don't use any external .exe command, so it should run faster. Also, it is clear enough to be understood with no problems, I think...
#echo off
setlocal EnableDelayedExpansion
for /D %%d in (*) do (
set "firstFile="
set "moreThanOneFile="
for %%f in ("%%d\*.*") do (
if not defined firstFile (
set "firstFile=%%f"
) else (
set "moreThanOneFile=true"
)
)
if not defined moreThanOneFile move "!firstFile!" "%%d"
)
You have a number of folders that all may or may not contain files within them, and you want to move all files to some other directory?
PowerShell is the new and improved super charged version of using a batch file, and this is how you'll do it.
Run PowerShell
paste in the following
dir -Recurse C:\FolderContainingManySubfolder | ? PSIsContainer | dir -Recurse | move-item -Destination T:\somePath -WhatIf
Replace C:\FolderContainingManySubfolder with the folder that has all of those other folders with one or two items each, and replace T:\somePath with the place you want the single files to go.
Run it, and you'll see a lot of 'What If' output, which shows you what would happen if you were to run the command. If you're happy with what you see, then remove the -WhatIf parameter from the end.

Remove all blank lines from *.txt files in the directory and subfolders in Windows

Searching, trying and crying I developed a code:
For /R %%G IN (*.txt) do for /f "delims=" %%a in ('more +1 %%G ^| find /v ""') do (set line=%%~a echo !line!) > new\%%G
Do someone know why does it loop forever?
What it is expected to do, is to remove blank lines in every *.txt file it founds in all subdirectories and put the new file with the same name in "new" folder. I can provide all "new" folders needed manually.
I'm not sure this would cause it to loop forever, but you are writing to a NEW folder that is in the same hierarchy that you are reading from. So it will process files that you just wrote. You will need a filter to prevent that.
Also, I think your output file name needs %%~nxG to get just the file name and extension, without the path.
There is a much simpler way to strip out blank lines. findstr . file will strip out empty lines. findstr /rc:"[^ ] will strip out empty lines and lines that contain only spaces.
#echo off
setlocal
set "outFolder=new"
for %%F in ("%outfolder%\.") for /r %%G in (*.txt) do if "%%~dpG" neq "%%~fF\" findstr /rc:"[^ ]" "%%G" >"%%~fF\%%~nxG"
But the simplest thing to do is just make sure your output folder is distinct from your source hierarchy
for /r %%G in (*.txt) do findstr /rc:"[^ ]" "%%G" >"\distinctPath\%%~nxG"
UPDATE
One thing that could cause your script to hang is that piped MORE will hang if the file has more than 64k lines. But I don't understand why you are using MORE in the first place.

Resources