for /f Not Reading Text File List - batch-file

I can't seem to get my batch file to copy only the files listed in a .txt file.
Inside the source folder are three PDF files.
They are apple.pdf, bat.pdf, and cow.pdf.
The text file is two lines containing bat.pdf on the first, and cow.pdf on the second. There is no punctuation, spaces, or anything.
The batch, the list, and the two folders are on my desktop.
#echo off
set src=C:\Users\weasel\Desktop\source
set dest=C:\Users\weasel\Desktop\dest
set list=C:\Users\weasel\Desktop\animallist.txt
for /f %%F in (%list%) do robocopy "%src%" "%dest%" *.pdf /R:1
I want only the animals in the list to be copied, but the code is just copying all .pdf files it can find as if only the robocopy was there alone. I end up with apple, bat, and cow in my destination folder.
I seem to be messing up the "for /f %%F in (%list%)" part, but I don't really know this coding and I can't find anything online that dumbs it down enough for me.
Any help would be greatly appreciated. Thank you.

You haven't included the metavariable in the list. *.pdf means "any file with a .pdf extension."
Try %%F*.pdf instead - or perhaps %%F.pdf if you file is jaguar.pdf and you want only that file.
Note also
The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned.
Use for /f "usebackq" %%F in ("%list%") to allow a filename containing spaces to be processed
Use for /f "delims=" %%F in (%list%) to allow a data lines containing spaces to be assigned to %%F
Use for /f "usebackqdelims=" %%F in ("%list%") to combine the two

Related

Copy list of files to specific folder locations

I have ~10,000 files in one folder. I want to copy specific files to specific folders based on a text file. Is it possible to use a semicolon delimited text file where the first part of each line is the source path & file name and the second part is the destination path?
C:\Files\File1.txt;C:\Folder1
C:\Files\File2.txt;C:\Folder2
C:\Files\File3.txt;C:\FolderN\
What would the code look like? Is there a better way to achieve the same result?
I have an existing bat file I use to copy all of the files listed in a text file to one specific folder location (below) but in this case I need to send different files to different folders and I would rather not run my bat file 50 times, changing the destination path in the bat file each time...
for /f %%f in (%1) do (
copy %%f G:\Files\PutFilesHere
)
It looks like this:
#echo off
setlocal enableextensions enabledelayedexpansion
for /f "usebackq delims=; tokens=1,2" %%I in (`type filelist.txt`) do (
copy /y %%I %%J
)
goto :eof
The for loop is told to use the result of a command (usebackq, for command type filelist.txt), to split at each ;, and to take elements #1 and #2. The fist is named as the variable (%%I, take care, case sensitive), and the second is the next letter, so %%J.
Then, the copy is trivial.
for /f "tokens=1,2delims=;" %%f in (%1) do ( copy "%%f" "%%g" )
see for /? from the prompt for documentation

7zip creating empty archives with batch file

I want to zip everything in a folder, EVERYTHING, but into individually named archives. For some reason every solution on the internet only zips folders, or fails to work at all.
Currently, I have
for /d %%X in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%X.zip" "%%X\"
Which I interpret to mean
for = initiate a loop
/d = I don't know what this means
%%X = I don't know what this means
in = not sure, I think it means current directory
(*) = I don't know what this means
do = execute the next thing in "..."
"C:\Program Files\7-Zip\7z.exe" = the thing I want done.
a = add to archive
-m9 = max compression
"%%X.zip" = make it a zip file, though I still don't know what %%X is.
"%%X\" = even if I knew what "%%X\" meant I don't know why it's here.
I have figured out replacing %%X gives the archive a name, so it seems to copy the name of the thing being targeted.
So if I guess, I think /d is "target folders" and %%X is the name.
So
for /d %%X in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%X.zip" "%%X\"
Says in English as I understand it: for every folder name in the current directory, use 7z to max compress it into a zip of the same name... except I don't know what to replace /d with to make it target files instead of folders. And targeting specific extensions would be even better.
I tried googling what does "/d in cmd mean," "what does %%X mean", etc. I don't seem to be getting correct results in the search, I think I'm being too vague for google.
UPDATE:
for %%i in (*) do "c:\Program Files\7-Zip\7z.exe" a -mx "%%i.zip" "%%i\*.*"
seems to make a zip file NAMED each item in the folder, but does not actually add any files to them. I tried adding /f, but it didn't work at all when I did that.
Additionally, the first time I posted this it was closed as a duplicate of Batch script loop which has almost nothing to do with my problem. Yes, I have a loop, yes that addresses batch loops, but no, it does not come close to solving my problem since my problem isn't with the loop itself., or if it does I have absolutely no idea why or how. So please, explain it to me. I did see the section where it says %%X is the variable, but that just means I suppose X could be anything I want it to be, and since in my update I indicated a secondary issue, I think the problem I'm having is with 7z and not the bat file.
The for command can be very confusing at first, however there is many videos and sites that show examples of how to use it.
To start with try for /? to see the built in help information.
The below code should be what you are after if i understand your requirements correctly.. if not then this should help you understand the principles and adjust for your needs.
for /F "tokens=*" %%a in ('DIR /A-D /B /ON "C:\Test Folder\"') do (
echo Processing File: C:\Test Folder\%%a
"C:\Program Files\7-Zip\7z.exe" a -mx1 -tzip "C:\Test Folder\%%a.zip" "C:\Test Folder\%%a"
echo.
)
pause
Now lets go through it line by line...
for /F "tokens=*" %%a in ('DIR /A-D /B /ON "C:\Test Folder\"') do (
/F Tells it to work with files instead of directories(/D)
in (' ') Contains the command that finds the filenames. Note the ' marks at each end of the command...they are important.
%%a Represents each value of a filename that the in() command passes it.
do ( ) What it should do with each %%a value it receives.
Now we get to the command that is finding the filenames and passing to the do () section as %%a
('DIR /A-D /B /ON "C:\Test Folder\"')
You can find more info on the this by running dir /?
/A-D Tells it to ignore Directories... only list files.
/B Output just the file names and not anything else like sizes or it will confuse the for command.
/ON Feed the filenames to the do() command in alphabetical order
"C:\Test Folder\" The folder that contains all the files we want to list/perform actions on. Make sure you include the trailing slash. Also use the "" marks or it wont work if a folder has a space in its name.
Write(echo) to the screen a message showing which file it is about to do.
echo Processing File: C:\Test Folder\%%a
You can find more information on how to use the 7zip command line functions at https://sevenzip.osdn.jp/chm/cmdline/syntax.htm
"C:\Program Files\7-Zip\7z.exe" a -mx1 -tzip "C:\Test Folder\%%a.zip" "C:\Test Folder\%%a"
"C:\Program Files\7-Zip\7z.exe" Run this program.... and pass it the following information (arguments/switches)
a Add files rather than extract, etc.
-mx1 Use the fastest compression method...but less space efficient.
-tzip Use the ZIP compression format
"C:\Test Folder\%%a.zip" Save the new "zip" file as this. (%%a will be replaced with the name of the current file... aka ChuckNorris.mpg which would end up as ChuckNorris.mpg.zip)
"C:\Test Folder\%%a" This is the actual file you want to zip.

Recursively append folder name to the files in Windows batch file

I would like to append my folder name to all the available .txt files inside a subfolder. Below is the file/directory structure. I need to achieve this in Windows BATCH script.
C:\Source\Source1\1\a.txt C:\Source\Source1\1\b.txt
C:\Source\Source1\2\a.txt C:\Source\Source1\2\b.txt
C:\Source\Source2\3\a.txt C:\Source\Source2\3\b.txt
The above files should be renamed like below:
C:\Source\Source1\1\1_a.txt C:\Source\Source1\1\1_b.txt
C:\Source\Source1\2\2_a.txt C:\Source\Source1\2\2_b.txt
C:\Source\Source2\3\3_a.txt C:\Source\Source2\3\3_b.txt
Similary, I have Source1...Source30 and under each source directory, I will have multiple folders with different numbers. I need to rename all the files under these directories and append the number(directory name) to the file name.
So far below is what I wrote:
for %%* in (.) do set CurrDirName=%%~nx*
echo %CurrDirName%
for /r %%x in (*.txt) do ren "%%x" "%CurrDirName%_%%x"
With this, I am able to achieve it in a single directory. I couldn't make it recursive. Could you guys please help me with this.
#echo OFF
SETLOCAL EnableExtensions
for /F "delims=" %%G in ('dir /B /S "C:\Source\*.txt"') do (
for %%g in ("%%~dpG.") do ECHO rename "%%~fG" "%%~nxg_%%~nxG"
)
pause
where the FOR loops are:
outer %%G loop creates a static list of .txt files (recursively), and
inner %%g loop gets the parent folder of every particular file.
The rename command is merely displayed using ECHO for debugging purposes. To make it operational, remove word ECHO (no sooner than debugged).
Moreover, I'd consider checking whether a particular file is already renamed…

shift file names with a batch file

Here is the file name format. The leading number is the layer and the second number is the material (3D printer).
01118_7.tif,
01118_6.tif,
01118_5.tif,
01118_4.tif,
01118_3.tif,
01118_2.tif,
01118_1.tif,
01118_0.tif
What I need to do is shift the files ending in _1, _4, _6 six places higher. So, 01124_1, 01124_4, 01124_6 while the rest of the files stay the same. I need to do it all the way down to layer 00112_*.
I'd like to do this via a batch file if I can. Was trying to follow a guide but the name format is tripping me up.
Basic excel format
I can't tell if you need to modify file names that appear within a text file, or if you need to rename files. Either way, I have a simple solution using one of two hybrid JScript/batch regex utilities:
Modify filenames within a text file using JREPL.BAT:
jrepl "^\d{5}(?=_[146]\.tif)" "lpad(Number($0)+6,'00000')" /i /j /f test.txt /O -
Rename files within the current directory using JREN.BAT:
jren "^\d{5}(?=_[146]\.tif$)" "lpad(Number($0)+6,'00000')" /i /j
Use call jrepl or call jren if you put the command within a batch script.
It took me awhile to understand that "shift file names six places higher" really means "add six to file name".
#echo off
setlocal EnableDelayedExpansion
set "numbers=/1/4/6/"
for /F "tokens=1,2 delims=_." %%a in ('dir /B /A-D *.tif') do (
if "!numbers:/%%b/=!" neq "%numbers%" (
set "newNum=1%%a+6"
ECHO ren "%%a_%%b.tif" "!newNum:~1!_%%b.tif"
)
)
If the names are not in files, but are lines of text placed in a text file, change the 'dir /B /A-D *.tif' command by the name of the text file.

Reading input from a file doesn't work for filenames containing spaces

I have a case where I have to move over 15,000 files. There are many duplicates, so I parsed them by MD5 and now I have a list of file names in an input file (files.txt).
I want to read from it, then copy the listed files to a new directory.
I pulled an old batch that someone had written as a two-part simple script and modified it.
It works for files without spaces. How can I get this to cover all file names?
Also, can't I put all of this into one file?
Cstart.bat:
for /f %%x in (files.txt) do call copyfiles.bat
copyfiles.bat:
set filename=%1
copy "C:\temp\%filename%" "C:\temp\pruned files\"
Your current code doesn't even pass the filename to copyfiles.bat, so it's not working with or without spaces. (If you need to confirm that, add echo %1 %filename & pause before the copy line in copyfiles.bat and run cstart.bat.)
With that being said, you can do it all in one file easily:
for /f %%x "tokens=1 delims=*" in (files.txt) do copy "C:\Temp\%%x" "C:\Temp\pruned files\%%x"
To make sure it works, just replace the copy in the line above with echo and run it from a command prompt.
I tested this with a text file named test.txt that contained the following:
One.txt
Two.txt
Three.txt
And Four.txt
with a batch file named testcopy.bat containing this:
#echo off
for /f "tokens=1 delims=*" %%x in (test.txt) do echo "C:\Temp\%%x" "C:\Temp\test this\%%x"
The above test showed this output:
e:\TempFiles>testcopy
"C:\Temp\One.txt" "C:\Temp\test this\One.txt"
"C:\Temp\Two.txt" "C:\Temp\test this\Two.txt"
"C:\Temp\Three.txt" "C:\Temp\test this\Three.txt"
"C:\Temp\And Four.txt" "C:\Temp\test this\And Four.txt"
for /f "usebackqdelims=" %%x in ("my file list.txt") do copy "C:\temp\%%~x" "C:\temp\pruned files"

Resources