FOR /F processing of CSV with differing number of variables - for-loop

I'm trying to write a batch script to move thousands of folders from their current location to a new location. I have a CSV with the original/new location info, as such:
[full path of current location],new_dir_1,new_subdir_2,[new_subdir_3],[etc],
In the past I've had good luck using FOR /F, and that's what I'm trying here.
for /f "tokens=1-4 delims=," %g in (text_file.csv) do xcopy "%%g" "d:\%%h\%%i\%%j" /e /i /y
Fails where there aren't enough tokens for variables and I get two trailing backslashes in my destination path.
for /f "tokens=* ....
Fails as well - my understanding was that "tokens=*" would create a token per comma-separated term but maybe I have that wrong? It appears, rather, to take the entire line as one token.
Is there a way to modify my "do" command to only create the destination path as deep as necessary (i.e., if new_subdir_3 doesn't exist, the path should be "d:\new_dir1\new_subdir_2\" and not "d:\new_dir1\new_subdir_2\")?
Thanks.

The tokens=* or tokens=1,* does not work as you think. It will set an aditional replaceable parameter that will contain the rest of the line after the last required token. That is, all the line in the first case or from the second to the end in the second case. But only one variable/replaceable parameter is defined for the *
There is an easy way to solve your problem . Just use an aditional for loop to handle the problematic path
for /f "tokens=1-4 delims=," %%g in (text_file.csv) do (
for %%a in ("d:\%%~h\%%~i\%%~j\.") do xcopy "%%~g" "%%~fa" /e /i /y
)
The %%~fa will return the full path generated by d:\%%~h\%%~i\%%~j\., but all the double backslashes will be removed in the process.

Related

BATCH: Delete parts of filename using substring not working

I have several .csv files in one folder. They are saved automatically but with spaces and execution date and time (in seconds) with amount of containing lines.
So far I was not able to run my powershell script with files containing spaces. So I tried to rename filenames using batch. so far nothing is working fine. Either in cmd-line or with a batch file.
Trying to loop in folder to find .csv is working but defining a string and then substring parts of the file not.
for %%i in ('dir *.csv /b /s') do set string = %%~ni
set substr=!string:~20,25!
echo !substr!
I tried first to use % instead of ! but didn't worked as well. Tried to use pipes for the loop as well, didn't worked.
So far my output is just
!string:~20,25!
My output has to be just the "real" filename of the report without anything else before or after it.
For example, do with that path and filename
C:\Users\Username\CSV_Files\Reportoutput Report_2017 2018-01-09T07_10_33.1924R.csv
this
C:\Users\Username\CSV_Files\Report_2017.csv
When I'm able to extract just the filename without any spaces or leading chars like "Reportoutput" (which is always the same) or starting time of report or containing lines in the report I could use that string and combine it with the path where files are saved.
Any ideas? Why is my "substring" not working at all? Do I miss some action? Some code?
I'm using windows.
Based on the file name structure you've presented and looping in one folder, (the current directory), as stated and used in your example code:
#Echo Off
For %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
If you wanted to check inside subfolders of the currect directory then change it to this:
#Echo Off
For /R %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
…and if you want to specify the base directory name then you can do so like the following two examples which use %UserProfile% for demonstration purposes, (change as appropriate).
#Echo Off
For /R "%UserProfile%" %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
and:
#Echo Off
CD /D "%UserProfile%" 2>Nul||Exit /B
For /R %%A In ("* * *.csv"
) Do For /F "Tokens=2" %%B In ("%%~nA") Do Ren "%%~A" "%%B%%~xA"
Instead of splitting the names using character numbers, this simply takes the second token of the file name string delimited by spaces and adds the original file extension to it in a rename command.

How do I write a batch script to search for a specific file based on folder name?

I need to write a batch script that searches for occurrences of a file named SQLite.Interop.dll in a certain directory. There will actually be many occurrences of this file nested under different subdirectories, and specifically I'd like it to find the one where the folder name is net45.
I started to try and write a batch script myself by piecing together different StackOverflow answers, but ultimately didn't get very far. Here's my initial, feeble attempt:
#setlocal enableextensions enabledelayedexpansion
#echo off
for /r C:\Specified\Directory %%i in (SQLite.Interop.dll) do (set str = %%i & if x%str:net45=%==x%filestr% (copy %%i ./SQLite.Interop.dll & goto BreakStmt)
:BreakStmt
endlocal
Things not yet working:
The Specified Directory path on the for /r statement
Substring searching for net45 in the file path
Not sure if & is the proper way to chain commands?
General syntax... I'm a bit like a fish out of water with this batch stuff...
Use recursive dir /s and filter the output by the directory name surrounded by \, parse the result with for /f:
for /f "delims=" %%a in ('
dir /s /b "C:\Specified\Directory\SQLite.Interop.dll" ^| find /i "\net45\"
') do copy /y "%%a" .
This method doesn't require delayed variable expansion.

batch rename multiple files in windows?

I wonder what's wrong with my coding, because it's not working
I want to rename all the png files inside Chris.
but it failed
for /f in ('C:/Users/Chris/Downloads/images/*.png')
do ren "C:\Users\Chris\Downloads\images\*.png" "%date:~10,4%-%date:~4,2%-%date:~7,2%_%HR%%time:~3,2%-img.png"
No need for /f in argument, no need for quotes but your missing a variable declaration
The variable should be used in the do-part otherwise the for is not realy helpful
the for will enumerate the full path so you need to strip the filename using ~n
the do-part must be directly behind the for-statement or it needs to be inside round brackets
here's the complete code:
for %%i in (C:/Users/Chris/Downloads/images/*.png) do (
ren "%%i" "%date:~10,4%-%date:~4,2%-%date:~7,2%_%HR%%time:~3,2%-%%~niimg.png"
)
If order to use a for loop, you need to specify a variable to use (even if you don't use a variable in the loop at all), otherwise you'll get a syntax error. While variables can only be one letter, this is pretty much the only time in batch that variables are case-sensitive, so you've got 52 letters, plus a few additional characters that I've seen used, like #. Additionally, do must always be on the same line as the ).
A for /F loop can process strings, text files, and other batch commands.
To process strings, use double quotes: for /F %%A in ("hello world") do echo %%A
To process batch commands, use single quotes: for /F %%A in ('dir /b') do echo %%A
To process text files, do not use any quotes at all: for /F %%A in (C:\Users\Chris\image_list.txt) do echo %%A
You may also want to go into the directory that you're processing just to make things easier.
pushd C:\Users\Chris\Downloads\images
for /F %%A in ('dir /b *.png') do (
REM I'm not sure what the %HR% variable is supposed to be, so I'm ignoring it.
ren "%%A" "%date:~10,4%-%date:~4,2%-%date:~7,2%_%HR%%time:~3,2%-img.png"
)

Batch File to insert char in file name for multiple files in a folder

I have a series of files that have names like this:
CHART_LOAN_6516_20130502.PDF
CHART_LOAN_2158_20130502.PDF
CHART_LOAN_78986_20130502.PDF
Each file always starts with CHART_LOAN_ but the next number is different and the last number is the date it was created.
I would like to insert an 0_ after CHART_LOAN_number_ for each file. As listed below:
CHART_LOAN_6516_0_20130502.PDF
CHART_LOAN_2158_0_20130502.PDF
CHART_LOAN_78986_0_20130502.PDF
Through my research I've found out to insert the char but not when the name is changing with each file.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET old=CHART_LOAN_
SET new=CHART_LOAN_0_
for /f "tokens=*" %%f in ('dir /b *.jpg') do (
SET newname=%%f
SET newname=!newname:%old%=%new%!
move "%%f" "!newname!"
)
The above code will change the static portion of the file to something I want, but I don't know how to modify the code to compensate for the changing loan number.
try this:
#echo off &setlocal
for /f "tokens=1-3*delims=_" %%i in ('dir /b /a-d *.pdf ^| find /i /v "_0_"') do ren "%%i_%%j_%%k_%%l" "%%i_%%j_%%k_0_%%l"
for /f "tokens=*" %%f in ('dir /b /a-d %old%*.pdf^|find /i /v "%new%"') do (
should see you right – but I'd add an ECHO  temporarily before the MOVE to check it's working properly.
Interesting that you'd use *.jpg in your original though. Rather unlikely to work, I'd guess.
The renamed files will match the pattern ..._0_... but the originals won't – the closest they'll come is with CHART_LOAN_0.pdf. Hence, you find all the filenames that don't match the new mask (/v) case-insensitive (/i). The /a-d guards against the remote possibility of a directory name that matches the old mask. The caret before the pipe tells CMD that the pipe is part of the command to be executed by the for.

using the command line how can i modify filenames

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.

Resources