Batch Rename Multiple Files? - batch-file

Similar question to these have been tons of time but, for what i want it is something different. I have tried searching but, not what I want.
Now I have certain (.txt) files in my folder (hidden-files) where certain text files (Multiple text files) are stored which have special characters (%!=^";#% ..etc) in them I would like to remove these special characters and replace them with (-) in a rename loop so the file(s) will be renamed.
Code (Got it from here somewhere) Edited to my use but, it didn't worked.
for /f "delims=" %%a in ('dir "%~dp0hidden-files\*.txt"') do (set "newname=%~nx1"
set "newname=%newname:!=-%"
set "newname=%newname:_=-%"
set "newname=%newname:==-%"
set "newname=%newname:%=-%"
echo ren "%%a" "!newname!")
Would appreciate any help. Cheers.

You have a whole host of problems with your code. I'm too tired to list them all, but there is one issue that is extremely difficult to solve with pure batch - there is no simple way to replace an = literal within a string using batch. The simplest (and perhaps most effective) way to accomplish this is to look character by character for the = and replace it via substring operations.
There are a bunch of other issues that require advanced batch techniques to solve.
I have a much simpler solution for you - my JREN.BAT utility uses regular expression replacement to rename files. It is a hybrid JScript/batch script that runs natively on any Windows machine from XP onward. Use jren /? from the command line to access the built-in help. You might want to use jren /? | more to see one screen at a time. I never use MORE because my console is configured with a large buffer that lets me scroll up to see past output.
Once you have JREN.BAT on your machine, preferably in a folder that is within your PATH variable, then all you need is the following to rename the files within the current directory - no additional batch script required:
jren "[!_=%]" "-" /fm *.txt
If needed, you can specify the folder as an option:
jren "[!_=%]" "-" /fm *.txt /p "c:\YourPathHere"
If you put the command within another batch script, then you will need to use CALL JREN, and the percent needs to be double escaped as %%%%. Percent literals must be escaped as %% within batch files, and the CALL requires an extra round of escape:
#echo off
call jren "[!_=%%%%]" "-" /fm *.txt /p "%~dp0hidden-files"
Update in response to comment
Adding (, ), [, and ] to the list of characters to replace is simple. The only trick is you must escape the ] as \] when it appears within a character set [....].
#echo off
call jren "[!_=%%%%[\]()]" "-" /fm *.txt /p "%~dp0hidden-files"
The other option is to place the ] immediately after the opening [.
#echo off
call jren "[]!_=%%%%[()]" "-" /fm *.txt /p "%~dp0hidden-files"
Regular expressions are incredibly powerful, but they can be confusing to the uninitiated. Use jren /?regex to access Microsoft's help page on all the supported regular expression syntax. There are loads of tutorials available on the internet, as well as web sites that allow you to conveniently test out regular expressions.
If you are developing a JREN command, I suggest you first use the /t option to test it out without actually renaming anything.
Last update for question in comment
File names cannot contain *, ?, |, <, >, \, /, : or ", so you don't need to worry about those characters. I'm not sure what you did, but I don't see the enclosing [...] to represent a character set. The following should work fine:
call jren "[`~!##$%%%%^&_ +=,';}{[\]()]" "-" /fm *.txt /p "%~dp0hidden-files"

Related

batch script to make batch script

ok simple i want to make a batch script that:
Makes export folder on users desktop
from new (as in not copying from somewhere) make a batch script in that folder that lists the contents of that folder after the user populates it and saves it to the desktop.
the problem i run in to is I'm trying to use echo to to copy the intended new script text from the original batch file into the new one like this:
#echo off
mkdir "C:\Users\%username%\Desktop\Export"
echo dir "C:\Users\%username%\Desktop\Export" /W /A:-H /B > "C:\Users\%username%\Desktop\Readout.txt" > "C:\Users\%username%\Desktop\Export\Directoty_List.bat"
the problem is that the echo command sees the ">" as the end of the statement and writes the first part to a desktop text file, but i want it to see the 2nd ">" as that. how do i work around this?
Thank you
As #Richard said in the comments, you can escape the > with a carret sign ^>. Most characters with special meaning in cmd can be escaped with the carret if you don't want to use that special meaning.
Normally the golden rule is: put everything between double quotes. Inside double quotes, the characters with special meanings are also escaped. Unfortunately the echo will print the quotation marks too so this won't really help in your case. It still is worth mentioning though, quotation marks help when setting values of variables with special characters, passing arguments with special characters, define paths with special characters (whitespaces or parenthesis for eg.), ... but not with echo.
There is one more advice I'd like to give: you can use %userprofile% instead of specifying the whole path C:\Users\%username%
#echo off
mkdir "%userprofile%\Desktop\Export"
echo dir "%userprofile%\Desktop\Export" /W /A:-H /B ^> "%userprofile%\Desktop\Readout.txt" > "%userprofile%\Desktop\Export\Directoty_List.bat"

%Computername% Up to a certain character for naming files

So we are running a backup script for my job and until now they just had the script pull the computer name and use that as the folder it creates. The problem that we are encountering is that when we go to then use the restore script it becomes useless.
Our computer names are for example SMITHT#-Year-A.
But I would like the batch script to not use the whole name because often this is used when we change the year of the computer. And because sometimes there are numbers after a persons name there are variying lengths so most of the knowledge I have on deciding start and stop points is coming up useless.
Is there a way to have the batch create a folder using the %COMPUTERNAME% function telling it to stop at the "-" so all we get is the name and number of the person?
To split a string at a certain character use for /F:
for /F "tokens=1 delims=- eol=-" %L in ("%COMPUTERNAME%") do (set SHORTNAME=%L)
This command line stores the string portion before the (first) - into variable SHORTNAME.
For details type for /? in the console window.
To use the above line in a batch script, replace %L by %%L.

How do I remove only certain words (not lines containing that word) from a text file with a Batch?

I'm writing a batch file that uses an output from a dir command to perform other tasks, I also want to use this same output (stored in dir_output.txt) for another use, but I don't want the file extensions at the end. right now the file looks like this:
barrier_1_post.p3d
barrier_1_section.p3d
but I want it to look like this
barrier_1_post
barrier_1_section
minus the file extensions, but I have no idea how to do this via the batch, I've looked through SO exhaustively but either I'm not finding the solution or I can't see the wood for the trees.
Any help would be amazing, I'm fairly new to batches.
for /f "delims=" %%a in (yourfilename.txt) do echo %%~na
should remove those extensions quite happily.
%~na delivers the name part only of the assumed filename in %a
(see for /? from the prompt for documentation)

Batch command to ignore specific files after dir command?

How do I set a batch script to ignore certain files? Like, not filter, but exact files.
Like
dir /b *.zip
Results in the file list
file1.zip
file2.zip
file3.zip
file4.zip
file5.zip
And I want to ignore the specific files
file3.zip
file4.zip
And end up with the file list result
file1.zip
file2.zip
file5.zip
How do I do this?
dir /b *.zip|findstr /v /i /g:"filecontainingexcludednamesonetoaline.txt"
should handle this task quite adequately.
On more information provided (best to provide relevant information at the start to prevent an endless revision cycle)
...
dir /b *.zip|findstr /x /v /i /g:"~f0"
....
goto :eof
---- this info at end-of-file. just plain text
---- files-to-exclude-from-listing
---- these last 3 lines are just comments playing no part in the script
exclude me.zip
and_me.zip
dont_show me.zip
Nearly the same as Magoo's answer, but without the extra file, and also with the addition of the /L option to force a literal match:
dir /b *.zip|findstr /vilx /c:"file1.zip" /c:"file2.zip"
This is a bit overkill for this problem, but you could also use my JREN.BAT utility. It is primarily intended for renaming files, but it does have an option to list files instead. The advantage of this utility is it allows you to specify very precise regular expression terms to match, as well as to specify files to exclude.
In this case, I use the /FM and /FX options to specify masks with normal Windows wildcard rules instead of using regular expressions.
jrepl "^" "" /list /fm *.zip /fx "file1.zip|file2.zip"
If you have complicated matching rules, then /RFM and /RFX could be used to specify regular expression masks instead.

trying to recursively search for files with a certain word in their file name using CMD (windows)

I'm trying to write a script that will search for all file recursively in a folder and run a command and/or list of commands on each file. Here's an example of how I need it to work:
Search folder for files containing "1080p" in the file name
Copy this file to a local directory but remove the "1080p" from the filename
Run another batch script on those files (I already have that part working)
All this needs to be automated.
I need to do this in the Windows command prompt and I'm willing to use any other programs required.
I'm already using SED in a similar batch script.
#echo off
setlocal disableDelayedExpansion
set "src=sourcePath"
set "dst=destinationPath"
set "search=1080p"
for /r "%src%" %%F in (*%search%*) do (
set "full=%%~fF"
set "name=%%~nxF"
setlocal enableDelayedExpansion
copy "!full!" "%dst%\!name:%search%=!"
endlocal
)
REM call your batch script here to process the copied files
You could have problems if the same filename exists in multiple source folders. But that is a general problem with your stated requirements.
Explanation:
%%~fF gives the full path to the file contained in %%F
$$~nxF gives the name and extension only of the file contained in %%F
type HELP FOR or FOR /? for more information about the modifiers available for FOR variable expansion.
!name:%search%=! uses delayed expansion to search the contents of name and replace the search value with nothing. In this example %search%=1080p. Note that the search is not case sensitive.
I need to use delayed expansion when doing search and replace within the loop because normal expansion using percents occurs when the statement is parsed. But the entire FOR construct, encluding the contents of the parentheses, is parsed as one logical statement. So normal expansion would give the value of name prior to the loop executing. That won't work :-) Delayed expansion gives the current value each time the line is executed.
Type HELP SET or SET /? for more information about search and replace and delayed expansion.
I need to toggle delayed expansion on and off because ! is a valid character in a filename, and %%F expansion will corrupt the value if it contains !.
I would recommend using cygwin to easily take advantage of some common Unix utilities, although you can probably locate windows compiled versions one by one (i.e. perl):
Find a list of files by name, execute a command on each:
find . -name \*1080p\* | xargs <command>
Find a list of files, create a list of move/rename commands to strip out '1080p' string:
find . -name \*1080p\* | perl -ne 'chomp();$x=$_;s/1080p//g;print"cp $x /target/$_\n"'
# add "| sh" to run the commands, or "> commands.sh" to generate a script
Command that should run in CMD only requiring PERL
dir /s /b | perl -ne 'chomp();$x=$_;s/1080p//g;print"copy $x c:\target\$_\n"' > cmds.bat
Adjust the scripts, of course, to do what you need. However, I believe this will accomplish your goal. There may be a clever way to do this with Windows CMD, but I am not a CMD expert. Unix utilities are (IMHO) much more straightforward!

Resources