I'm working with files with various extensions, such as .bmp, .txt, etc, and I'm in the process of sorting them around through a batch file. However there are some files without any extension that I would like to be able to specifically manipulate.
How can I target extension-less files alone? Such as moving/deleting them exclusively. Or moving files with extensions while ignoring extension-less files?
If you only want to view or process files with an extension, use this syntax:
dir /b /a-d [path] | findstr /l "."
Only files containing a dot will be displayed.
You can add this to the for statement to get the output to a processable variable.
Of course, you must add an escape character before the pipe character in the for sentence.
However, to perform the operation in the subdirectories as well, it is best to use the for sentence, as a dot may appear in the folder name. like this:
for /f "tokens=*" %d in ('dir /s /b /ad') do #dir /b /a-d "%d" | findstr /l "."
To do the opposite (showing only files without an extension) simply add the findstr /v parameter.
Related
I am fairly new to Batch files but this is my Batch File for displaying path for Jpegs, Mp3, Mp4 etc.
#echo off
setlocal
cd /d C:\
Echo
echo Files Paths :
dir /b *.mp3 /s
dir /b *.mp4 /s
dir /b *.jpg /s
endlocal
pause
1.) Is there anyway that I can exclude Microsoft and Windows (wallpapers, icons, sounds, etc) folder from my search?
2.) How do I save the results in this output file (which is already created) C:\output.txt
Thanks!
This is quite an easy task for the findstr command:
dir /S /B /A:-D *.mp3 *.mp4 *.jpg | findstr /V /I /C:"\\Microsoft\\" /C:"\\Windows\\" > "C:\output.txt"
The \\ represent one literal \ in order to ensure that only directories become excluded whose full names match the predefined names. Since findstr uses the \ as an escape character \\ is necessary.
As you can see it is not necessary to use multiple dir commands. The filter option /A:-D excludes any directories to be returned even if they match one of the given patterns.
The returned data is written to a file using redirection. To append to the file rather than overwriting it replace > by >>.
I'm using wordconv.exe to convert a bunch of a old doc files into docx. Afterwards I'd like to delete the original doc files.
When I run "del /S *.doc" on the command line it deletes both the doc and docx files. Anyway to get it to delete just .doc files?
Thanks!
Let's try to use something like this:
forfiles /s /m *.doc /c "cmd /c del #file"
The problem is the short 8.3 names of the files, because for internal cmd commands and also many external ones, wild-cards (*, ?) also match against them. For example, a file like important-document.docx has got a short name like import~1.doc, which is matched by *.doc.
There are some commands that treat wild-cards differently:
forfiles (as already demonstrated in the answer by Michał Mielczarek):
forfiles /S /M "*.doc" /C "cmd /C if #isdir==FALSE del #relpath"
The #isdir query checks whether the current item is a file and lets skip folders.
where:
for /F "delims=" %%F in ('set "PATHEXT=" ^& where /R "." "*.doc"') do #del "%%~F"
The surrounding for /F loop captures the result of where. The command set "PATHEXT=" deletes the PATHEXT variable in the cmd instance in which where is executed, because this also regards that variable, so a file like important-document.doc.com could also be matched unintentionally with a default value of PATHEXT of .COM;.EXE;.BAT;.CMD, for instance.
Although the where approach appears a little bit more complicated, you might prefer it, because it is faster than forfiles, particularly when having a huge directory tree.
N. B.:
forfiles /M "*.*" does not match files (or folders) with no extension (so use /M "*" to match something like testfile), but where "*.*" does, so this indicates that these two commands have their own individual wild-card handling/substitution routines.
for /f "tokens=*" %%? in ('dir /b /a-d /s *.doc') do if /i "%%~x?"==".doc" del "%%~f?"
You can add if exist "%%~dpn?.docx" before del, if .doc and .docx are in same folder.
I am trying to copy from one directory to another, all files that have 2 digits format (ex. 12.txt, 15.pdf, 25.doc... etc), this is in Windows.
In Linux this works:
cp -t target_directory {10..99}.*
In Windows what will be the solution?
This is ugly but should work
for /L %i in (10,1,99) do #copy %i.* dest_folder_here >nul 2>&1
It tries every file in the range suppressing conditions. Adjust copy to overwrite if needed.
I would filter for the correct files by findstr, like this:
for /F "delims= eol=|" %%I in ('dir /B /A:-D "??.*" ^| findstr /X "[0123456789][0123456789]\.[^.]*"') do copy "%%~I" "\path\to\destination"
I avoided to use range expressions [0-9] because they might also match ², ³.
If you also want to match files with no file name extension, change the search string to [0123456789][0123456789] [0123456789][0123456789]\.[^.]*.
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).
how can i modify filenames in a folder based on delimiters in the filename?
I have a folder with images that get picked up by a different program based on a schedule- the program can only analyze the images if it contains just the main name (sku#) not the additional data that the photographers add after the name
using the command line can i run some sort of script to modify the filenames & delete all characters from after an underscore or hyphen (also need to delete underscore or hyphen)
(i dont know if & how its possible to do this thru the windows command line but i do have the option of running such a 'script' in cygwin- I prefer to use whatever works best...)
I haven't had a need to do this: but with a quick search I found this link on another Stack Exchange site.
A few people uploaded some powershell scripts. The top answer is a GUI tool to do mass name-changes.
There is this CMD example:
dir /B > fileList.txt
for /f "tokens=1,2,3" %i in (fileList.txt) DO ren "%i %j %l" %l
The first line outputs the list of files into a file called fileList.txt. The second line separates each of the names in the list into 3 parts, the #, the "-" and the rest of the name. For each of those it does the rename command.
#ECHO OFF
SETLOCAL
FOR /f "delims=" %%a IN ('dir /b /a-d ^|findstr "_ -"') DO (
FOR /f "delims=_-" %%i IN ("%%a") DO ECHO REN "%%a" "%%i%%~xa" 2>nul
)
FOR /f "delims=" %%a IN ('dir /b /a-d ^|findstr "_ -"') DO ECHO failed ON "%%a"
This should do the job.
First step is to perform a directory listing in /b basic form (without headers - names only) and /a-d without directory names. This is filtered by findstr on (either underscore or dash) and %%a acquires each filtered filename in turn.
The next step is to take those filenames and split them into the parts on either _ or -. The first token (up to, but not including the delimiter) is applied to %%i, so the rename required is from "%%a" (the original filename) to "%%i%%~xa" - the first token+the extension from the original filename.
It's quite possible that the attempt to rename will fail because the new name already exists, so the error message is simply ignored (2>nul)
Finally, look for any un-renamed files and report them (optional, of course)
Note that the REName command is merely ECHOed. This ensures nothing is actually changed while you verify this is what you want to do. Simply remove the ECHO before the REN to activate the rename.