Rename files, moving date part of name from beginning to end - windows

I have filenames that come with the date at the beginning of their names, e.g. 20171015….txt.
I currently use a batch file to strip off the first 8 characters and this has worked well. However I'd like to now keep the date but move it to the end of the file name.

With the file name without extension set as a variable, %Variable%:
Ren "%Variable%.ext" "%Variable:~8%%Variable:~,8%.ext"
Or if performed within some sort of loop and delayed expansion enabled, i.e.SetLocal EnableDelayedExpansion:
Ren "!Variable!.ext" "!Variable:~8!!Variable:~,8!.ext"

Related

Script to move all files starting with the same 7 letters in a different folder named after first 7 chars of its future content

All files are in a directory (over 500 000 files), named in the following pattern
AR00001_1
AR00001_2
AR00001_3
AR00002_1
AR00002_2
AR00002_3
I need a script, can be both batch or unix shell that takes everything with AR00001 and moves it into a new folder that will be called AR00001, and does the same for AR00002 files etc
Here's what I've been trying to figure out until now
for f in *_*; do
DIR="$( echo ${f%.*} | tr '_' '/')"
mkdir -p "./$DIR"
mv "$f" "$DIR"
done
Thanks
// Update
Ran this in the CMD
for %F in (c:\test\*) do (md "d:\destination\%~nF"&move "%F" "d:\destination\%~nF\") >nul
Seems to be almost what I wanted, except that it does not take the first 7 characters as a substring but instead creates a folder for each file :/ I'm trying to mix it with your solutions
#echo off
setlocal enabledelayedexpansion
for %%a in (???????_*) do (
set "x=%%a"
set "x=!x:~0,7!"
md "!x!" >nul
move "!x!*" "!x!\" 2>nul
)
for every matching file do:
- get the first 7 characters
- create a folder with that name (ignore error message, if exist)
- move all files that start with those 7 characters (ignore errormessages, if files doesn't exist (already moved))
The following achieves the desired effect and checks for non-existence of the target directory each time before creating it.
#echo off
setlocal ENABLEDELAYEDEXPANSION
set "TOBASE=c:\target\"
set "MATCHFILESPEC=AR*"
for %%F in ("%MATCHFILESPEC%") do (
set "FILENAME=%%~nF"
set "TOFOLDER=%TOBASE%!FILENAME:~0,7!"
if not exist "!TOFOLDER!\" md "!TOFOLDER!"
move "%%F" "!TOFOLDER!" >nul
)
endlocal
In the move command, by moving only the current file rather than including a wildcard, we ensure that we're not eating up file names that might be about to appear the next time around the loop. Keeping it simple, assuming that efficiency is not of prime importance.
I'd recommend prototyping by creating batch files (with a .bat or .cmd extension) rather than trying to do complex tasks interactively using on one-liners. The behaviour can be different and there are more things you can do in a batch file, such as using setlocal to turn on delayed expansion of variables. It's also just a pain writing for loops using the %F interactively, only to have to remember to convert all those to %%F, %%~nF, etc. when pasting into a batch file for posterity.
One word of caution: with 500,000 files in the folder, and all of the files having very similar prefixes, if your file system has 8.3 directory naming turned on (which is often the default) it is possible to run into problems using wildcards. This happens as the 8.3 namespace gets more and more busy and there are fewer and fewer options for ways the file name can be encoded in 8 characters. (The hash table fills up and starts overflowing into unexpected file names).
One solution is to turn that feature off on the server but that may have severe implications for any legacy applications. To see what the file looks like in 8.3 naming scheme, you can do, e.g.:
dir /x /p AR*
... which might give you something like (where the left hand name is the one converted to 8.3):
ARB900~1.TST AR15467_RW322.tst
AR85E3~1.TST AR15468_RW322.tst
ARDDFE~1.TST AR15469_RW322.tst
AR1547~1.TST AR15470_RW322.tst
AR1547~2.TST AR15471_RW322.tst
...
In this example, since the first two characters seem to be maintained, there should be no conflict.
So for example if I say for %a in (AR8*) do #echo %a I get what might at first seem to be incorrect:
AR15468_RW322.tst
AR18565_RW322.tst
AR20376_RW322.tst
AR14569_RW322.tst
AR17278_RW322.tst
...
But this is actually correct; it is all the files that match AR8* in both the long file name and short file name formats.
Edit: I am aware in retrospect that this solution looks very similar to Stephan's, and I had browsed through the existing answers before starting work on my own, so I should credit him. I will try and save face by pointing out a benefit of Stephan's solution. Its use of wildcards should circumvent any 8.3 naming issue: by specifying the wildcard as ???????_*, it only catches the long file names and won't match any of the converted 8.3 file names (all of which are devoid of underscores in that position). Similarly, a wildcard such as AR?????_* would do the same.
With bash, you'd write:
for f in *; do
[[ -d $f ]] && continue # skip existing directories
prefix=${f:0:7} # substring of first 7 characters
mkdir -p "$prefix" # create the directory if it does not exist
mv "$f" "$prefix" # and move the file
done
For the substring expansion, see https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion -- this is probably the bit you're missing.

Processing of the file names

I have a folder with a files inside with a long names like:
08_29_2017.AT1_dry_apo.3rep.step7_1.xtc
each file begins with a current data in a format like
dd_mm_yyyy.
My bash script loops all the files and defines only the relevant part of the file name in a new variable:
for traj in ${all_xtc}/*.xtc; do
traj_name3=$(basename "$traj")
traj_name="${traj_name3/.xtc/}" # here I remove xtc from the name
# here I need to add something to remove the date from the begining of the file
what should be passed here to remove a date from the beginning of a file name?
Thank you!
You can do what you want in two parameter expansions:
for traj in "$all_xtc"/*.xtc; do
traj=${traj##*/[0-9][0-9]_[0-9][0-9]_[0-9][0-9][0-9][0-9]}
traj=${traj%.xtc}
echo "$traj"
done
The first one removes everything up to the last slash (equivalent to basename), followed by the date. The second one removes the .xtc from the end.
The first expansion isn't at all strict about the date, since it would also match 98_76_0000, but it's probably good enough in this case. You can add a . to the end if you want to remove that as well.

Windows delete with wildcards deleting erratically

This is driving me crazy. Basically, I have a program that outputs tables to a flat file for multiple databases with the same structure. These files get named in the format tablename_####.dat, where #### is the 4 digit company number. After these are all created, the program then combines all of the files by tablename, and adds a timestamp on the end. So, the final file name is in the format tablename_YYYYMMDD_HHmmSS.dat. Finally, I want to delete all of the individual .dat files, leaving only the combined, time stamped files.
This works just fine for all of the tables, except for the table VEX. For example, I have files:
VEX_1234.dat
VEX_5678.dat
VEX_0987.dat
which combine to form VEX_20150414_144352.dat. After this, I run the command:
`del *_????.dat`
This deletes all of the tables' individual files (V_1234.dat, PAT_9534.dat, etc.), while leaving the combined files (V_20150414_142311.dat, PAT_20150413_132113.dat) ...except for VEX. It deletes both the individual files and the combined file. Shouldn't this only delete files that end with an underscore, 4 characters, and ".dat"?
I know this has to be something really simple that I'm missing. What is going on?
Most likely your issue is caused by short 8.3 file names.
The ? wildcard can match 0 or 1 character if it precedes a dot. Your file mask of *_????.dat will match any name that has any number of characters, followed by a _, followed by 0 to 4 characters, followed by the .dat extension. The tricky thing is it will attempt to match both the long file name, and any short 8.3 name, if it exists.
Try issuing dir /x *.dat, and look at the short name of the problem file. I suspect it will match your file mask.
There are patterns with how short names are derived, but there is no way to predict the short name of any given file unless you are aware of all existing short names within the folder, and then you would be relying on undocumented behavior.
This is a fairly common problem. If your files are on an NTFS drive and you have admin rights, then you can disable short file name generation. But this does not remove already existing short names.
The best general solution is to pipe DIR /B through FINDSTR to remove the unwanted files, and process the result with FOR /F to delete each file individually. The FINDSTR below will exclude file names that contain two or more _ characters.
for /f "delims=" %%F in ('dir /b *.dat^|findstr /v "_.*_"') do del "%%F"

How to Find and Replace file content in batch script

For example I have the file sample.txt. This file contains:
1111101
2222203
3333303
44444A1
55555A1
66666A1
Now, I want to replace user defined specific pattern. For example I have other file where use defines what he want to replace with. Example the file name is replace.txt. This file contains 2 Columns, first column for the pattern and the 2nd column for the text to be replace.
Example:
replace.txt
2222203 2222203ADD
55555A1 55555A1SUB
Now, when the batch file has been executed, I would like the file sample.txt to have a contents like this:
1111101
2222203ADD
3333303
44444A1
55555A1SUB
66666A1
Also is it possible to have a "space" as part of the text to be replace(column 2?
You may use FindRepl.bat program that is a Batch-JScript hybrid application that perform these replacements in a very efficient way via regular expressions; it uses JScript language that is standard in all Windows versions from XP on. In the basic use of FindRepl.bat you redirect the input file to it and place two strings as parameters, a "search" string and a "replacement" string. For example:
< sample.txt FindRepl.bat "2222203" "2222203ADD"
Previous command will replace all 2222203 strings in the file by 2222203ADD. In order to perform the replacement of several strings, you may include several alternatives in both the search and replacement strings separated by a pipe character (this is called alternation), and include the /A switch to select this feature; for example:
< sample.txt FindRepl.bat "2222203|55555A1" /A "2222203ADD|55555A1SUB"
If you want to define the set of replacements in a separated file, you just need to load the strings from the file, assemble the alternations in two variables and use they in FindRepl preceded by an equal-sign to indicate that they are variables, not literal strings. If you want that the strings may have spaces, then you must use a different character to separate the search and replace parts in the file. For example, if you use a colon in replace.txt file this way:
2222203:2222203 ADD
55555A1:55555A1 SUB
Then the Batch file below solve your problem:
#echo off
setlocal EnableDelayedExpansion
set "search="
set "replace="
for /F "tokens=1,2 delims=:" %%a in (replace.txt) do (
set "search=!search!|%%a"
set "replace=!replace!|%%b"
)
set "search=!search:~1!"
set "replace=!replace:~1!"
< sample.txt FindRepl.bat =search /A =replace
You may download FindRepl.bat and review an explanation of its use from this site; you must place it in the same folder of previous program or, better yet, in a folder included in PATH variable.

Renaming file with Batch variable

I have the following code:
set DATE=%date%
echo %DATE%
set DAY=%DATE:~0,2%
echo %DAY%
rename file09.txt file%DAY%09.txt
pause
It is supposed to rename a text file and put the day of the month in the file name. I am however getting a syntax error on the rename command.
I think the problem is in inserting the variable into the file name. Any help would be appreciated. The echos are just in the program for my own reference.
As has already been stated - your code as pasted had trailing spaces on many lines and the spaces often matter. I posted this because you had reused the system DATE variable name and that causes issues, and to show you that quotes are often helpful - and needed with long filenames.
set "D=%date%"
echo "%D%"
set "DAY=%D:~0,2%"
echo "%DAY%"
rename "file09.txt" "file%DAY%09.txt"
pause
you might have trailing spaces in the set command. Just try this:
set "DAY=%DATE:~0,2%"
btw. with set DATE=%date% you doesn't create a new variable. Variables must have case insensitive unique Names.
The problem was the date configuration, because of that the content of the variables is wrong.
Really use quotation marks worked as it ensures full name if the variables have spaces or unusual characters.
Review my post for view the Endoro answer..it works right for me
Renaming file with Batch variable doesnt work with another user profile
"Renaming file with Batch variable doesnt work with another user profile"

Resources