I want to move files according to folder names.
1.Some folder names have been written in b2.txt. In my b2.txt, every line contains one or two or three words, connected by space or "-". Like this:
transfer print
anti-foamer
insect
fibre reinforced plastic
2.My files are in "E:\JP-XIN\".
3.In E disk, there must exist one (only one) folder name consisting of one line in b2.txt.
My question is how to set every line in b2.txt exactly as variable.
In the following code, "%%k" is the file name gotten by searching, "%%l" is the path to the folder gotten by searching. The code did not work correctly.
#echo off
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in (b2.txt) do (
set VAR=%%a
for /f "delims=" %%k in ('dir /s/b/a-d E:\JP-XIN\*.pdf E:\JP-XIN\*.txt ^| findstr /i /c:"!VAR!"') do (
for /f "delims=" %%l in ('dir /s/b/a:d-h E:\ ^| findstr /i /c:"!VAR!"') do (
if not "%%l"=="" move "%%k" "%%~fsl"
)))
pause
I had some time to spent so I worked overtime in how to solve what I think your problem is.
If your requirements are these:
The b2.txt file contains several folder names, with possible spaces.
In E:\ there is one folder that is contained in b2.txt.
In E:\JP-XIN\ there are several *.pdf and *.txt files.
and you want to:
Locate the folder that is contained in b2.txt, and
Move to it the *.pdf and *.txt files that have the same name of the folder
then the Batch file below solve your problem:
#echo off
for /f "delims=" %%a in (b2.txt) do (
if exist "E:\%%a" (
move "E:\JP-XIN\%%a.pdf" "E:\%%a"
move "E:\JP-XIN\%%a.txt" "E:\%%a"
)
)
If the .pdf and .txt are the only files with that name, then the two move commands may be joined in just one:
move "E:\JP-XIN\%%a.*" "E:\%%a"
If this is not your problem then, please, tell us what your problem is!
You need to use tokens=* to return the entire line as a single variable.
for /f "tokens=* delims=" %%a in (b2.txt) do (
You can also write things like tokens=1,2* which makes the first variable token 1, the second variable token 2, and the third variable the rest of the line. So the text:
Several words on a line.
Would split to:
%%a = Several
%%b = words
%%c = on a line.
Related
Good Morning!
Coming from another article, which i tried to adopt, but failed, i would like to ask my question in a separate post. I need to achieve two things:
Copy all files that contain a certain string in their filename from one directory to another, but only if that file does not already exists in that target directory. The filename could be something like EventLog_12345.txt and i would want to copy only the files where the filename contains EventLog.
In a set of files identify in every .txt file a certain string. This string indicates the line that contains the string i am looking for. I want to get to the end of this line and save the .txt file as a new .txt file with a new name based on the string i find at the end of this line. Example: My file is EventLog_12345.txt and somewhere in this file there is a line like this:
2018-06-22 08:21:19 0133 LET vVariable = 'h**ps://somedomain.com/test/1/2/4/jobs/joblog.XML'
The string indicating the line is vVariable.
The string i want to use within the new filename in this example is joblog.xml. The file should be stored as a new .txt file with the name: joblog_12345.txt. Note, that the length of the line can vary; so can the length of the domain string; also the names of the XMLs are different. The constant is that i always
want to have the name of the XML file which is always the last piece of the domain.
Adding info on efforts so far
Copy & Paste - this is actually working, but does not check whether a file already exists:
#echo off
for /f "delims=" %%a in (
'xcopy /l /e /y "\\myPath\*EventLog*.txt" "D:\Target\" ^|find "EventLog"'
) do copy "%%a" "D:\Target\"
For the identification of string and then SaveAs i dont really have anything. I was basically hoping i could somehow adjust the solution provided here: (Rename text files based on multiple strings in their contents)
For 1st
#echo off
Set "Target=D:\Target\"
for /f "delims=" %%A in (
'xcopy /l /e /y "\\myPath\*EventLog*.txt" "%Target%" '
) do if not exist "%Target%%%~nxA" copy "%%A" "%Target%"
For 2nd
process a list of files containing vVariable with findstr /I /M "vVariable" *_*.txt in %%A
Split the found name at the underscore %%B
search file to get the Line and exchange all / in the line to spaces to then
get the very last element in %%D
use %%~nD without extension to form the new name
:: Q:\Test\2018\05\22\SO_50982243.cmd
#Echo off & Setlocal EnableDelayedExpansion
For /f "delims=" %%A in ('findstr /I /M "vVariable" *_*.txt ') Do (
For /f "tokens=2delims=_" %%B in ("%%~nA") Do (
For /f "delims=" %%C in ('findstr /I "vVariable" ^<"%%A"') Do Set "Line=%%C"
Set "Line=!Line:/= !"
For %%D in (!Line!) Do Set "NewName=%%~nD_%%B%%~xA"
Echo Ren "%%~A" "!NewName!"
)
)
Sample output based on your information
> SO_50982243.cmd
Ren "EventLog_12345.txt" "joblog_12345.txt"
If the output looks OK remove the echo in front of ren to really rename.
I'm trying to make a .bat file which iterates through every file in the directory which the .bat file is in, and renames all the files which follow the naming convention of MM_DD_YY*.* to YY_MM_DD*.*.
For example, 05.20.16 MyFile.txt would become 16.05.20 MyFile.txt.
I've managed to iterate through the filenames, but I'm having trouble with making a substring of the beginning 8 characters and comparing them to the format of ##.##.##.
#echo off
setlocal EnableDelayedExpression
for /f %%i in ('dir /b') do (
set fn=%%i
:: Need to compare first 8 chars to ##.##.##
if %fn:~0,8%==??.??.?? echo FollowsFormat
)
Any help is appreciated!
Provided:
the date in the file name is always followed by a space.
You can use delimiters . and spaceto seperate date elements and remaining file name into for variables %%A - %%D and rearrange them in the desired order.
To better distinguish old from new format I suggest to change the delimiter (at least temporarily) to a - and extend the year to 4 digits.
#echo off & setlocal EnableDelayedExpression
for /f "tokens=1-3* delims=. " %%A in (
'dir /b /A-D "??.??.?? *.txt" ^| findstr "^[01][0-9]\.[0-3][0-9]\.[0-9][0-9].*"'
) do Echo Ren "%%A.%%B.%%C %%D" "20%%C-%%A-%%B %%D"
For security reason the batch only echoes what it would rename
until you remove the echo in front of ren if the output looks OK.
I am trying to write a simple batch file that will list the subfolders that begin with "#" of a particular folder in which the batch file resides, sort those files by date modified, and tell me the number of files within each subfolder. Here is my code, which works perfectly except that it always outputs the number of files as "0" which is incorrect:
FOR /F "tokens=* delims= " %%D IN ('DIR *.* /-P /O:G-DE ^| FIND "#"') DO (
FOR /F %%K IN ('DIR "%%D" 2^>NUL ^| FIND "File(s)" ^|^| ECHO 0') DO (
ECHO %%D %%K>>Test1.txt
)
)
When I do a test batch file just to output the number of files in the subfolders, it works (although it gives the number of files in the folder and total number of files as well, but at least I'm getting the number of files per subfolder):
FOR /F %%K IN ('DIR /S ^| FIND "File(s)"') DO ECHO %%K >>Test2.txt
I just can't seem to get it to work when I combine the two bits of code to simply give me the names of the subfolders + number of files (one line per subfolder). Any help would be greatly appreciated!
Thank you!
The command line dir *.* /-P /O:G-DE | find "#" you are using actually returns files and directories that contain #. To get only directories that begin with #, use the command line dir /-P /A:D /O:-DE "#*". The switch /A:D lets dir return directories only; the pattern #* means items beginning with #, there is no need for find.
Now let us use for /F to walk through all items. For this, add the switch /B to dir to avoid any headers in the output and return a pure directory list:
for /F "delims=" %%D in ('
dir /B /-P /A:D /O:-DE "#*"
') do (
rem print each item:
echo "%%~D"
)
So let us concentrate on the number of files contained in each of the listed directories now. Your method using dir and searching for the line containing the text File(s) by find works fine basically. There is no need for echo 0 as dir returns the summary line also for empty directories. But you need to consider items that contain the string File(s) in their names. So the following code should work:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
> "Test1.txt" (
for /F "delims=" %%D in ('
dir /B /-P /A:D /O:-DE "#*"
') do (
for /F "tokens=1 delims= " %%K in ('
dir /-P "%%~D" ^| find "File(s)"
') do (
set "numItems=%%K"
)
echo "%%~D" !numItems!
)
)
endlocal
The redirection to a text file is done once rather than for every loop iteration. I also removed the 2> nul from the inner dir command as the enumerated directory will exist for sure (it is retrieved by the outer dir), so there will be no error messages.
The inner loop does not produce an output but assigns the number of files to a variable numItems. This loop normally iterates once, but if a file contains File(s) in its name, it iterates twice -- the first time for the file and the second time for the summary line. Since the variable numItems is overwritten, it always contains the last value which is the expected number (as the summary line is at the end).
This method requires to produce the output by an echo after the inner loop. This requires delayed environment variable expansion, which is enabled by the setlocal command and actually used by the syntax !numItems! rather than %numItems%. Type set /? for more information on this.
Note that the search string File(s) need to be adapted accordingly on non-English systems.
I have a directory full of scanned documents, grouped into different folders and subfolders based on year, month and date. Each scanned document has a unique barcode number assigned to its filename.
What I'm trying to do is write a command that will use a list of these barcodes in a csv file and search the directory and subdirectories for the relevant files, then copy them into a new folder I have on my local drive.
This is what I have so far..
#echo off
setlocal enabledelayedexpansion
set id=0
if not exist AllFilesFolder mkdir AllFilesFolder
set "theDir=Z:\INVS"
for /f "delims=" %%i in (theFile.csv) do (
copy %theDir%\%%i.* "C:\Data")
Really hope someone could help me out on this one. I've probably wasted more time trying to get it to work than trying to find the files the old-fashioned way, but if I could get it working it'd save time in the future.
Many thanks,
Dave
I hope I interpreted you question right.
I assume, theFile.csvcontains only the barcodes, without the complete path:
for /f "delims=" %%i in (theFile.csv) do (
for /f %%j in ('dir /s /b %theDir%\%%i.*') do (
copy "%%j" "C:\Data"
)
)
Here's another option: the usebackq allows thefile.csv to be specified by path as well, and to contain spaces or & in path or filename.
for /f "usebackq delims=" %%a in ("theFile.csv") do (
for /r "%theDir%" %%b in ("%%a.*") do copy "%%b" "C:\Data"
)
I need help with a script that first finds all files in a directory with a certain string, then uses the filenames in a variable to be used in a script.
So:
Find files and filenames
Saves file?
Start some kind of loop? that changes a variable then executes the
belonging script
Repeat till all filenames have been used.
My code here..
#Echo off
For /r C:\work %%G In (*) Do #Findstr /M /S "string" > filenames.txt %%G
Set Var1=0
For %%G In (*) Do (
Var1=<filenames.txt (???)
script
script
I haven't writen "script" myself and friend help me with it, if you would like to see it do you need to wait until I can get to my other computer at home.
Thanks on beforehand!
Find files and filenames
Saves file
set "search=what I want to find"
(for /f "delims=" %%a in ('dir /a-d /b /s "C:\work" ^| findstr "%search%"') do echo (%%~fa)>filenames.txt
Start some kind of loop? that changes a variable then executes the belonging script
Repeat till all filenames have been used.
for /f "delims=" %%a in (filenames.txt) do (
REM here do something inside the loop
REM until all file names from filenames.txt were processed
)
This is designed to find files in c:\work that match a string, and echo the filenames.
#echo off
cd /d "c:\work"
for %%a in ("*string*") do (
echo "%%a"
)