I have problem with following simple dos command:
FOR %%f IN (.\07_PROCEDURES\DataSources\*.sql) DO echo "%%f"
It does some action for every file with sql extension. Everything works fine, except long names. When directory contains files, with sql_ extensions, they are picked up too. But this behavior depend on whether 8.3 files are turned on or off on file system. If they are turned on (default choice on most computers) sql_ are passed, because extension is cropped.
How to force for fetch long file names ? Thanks !
P.S. Do not offer powershell upgrade.
You can try to examine the extension in the loop itself
for %%f in (*.sql) do (
if /i "%%~xf" EQU ".sql" echo %%f
)
You can try something like this:
for /f "usebackq delims=" %%f in (`dir /b .\*.sql ^| findstr /r .*\.sql$`) do #echo "%%f"
Related
I'm trying to automate renaming of files based on a CSV such as the one shown below:
Name,FullName
John,JohnDoe
Jane,JaneDoe
Joe,JoeDoe
Let's say I have 3 text files within the same folder of my .bat called John.txt, Jane.txt, Joe.txt and I want to rename John.txt to JohnDoe.txt, etc.
I am getting "The system cannot find the file specified" no matter how much I alter the filepath in my rename. Here is a basic rundown of what I have. What am I doing wrong here or what other way should I approach this? I appreciate all feedback.
#echo off
setlocal enabledelayedexpansion
set csvpath=C:\Users\user1\OneDrive\Documents\BatchExamples\stuff.csv
FOR /F "usebackq skip=1 tokens=1,2 delims=," %%g IN (!csvpath!) do (
set person=%%g
set name=%%h
echo My name is !person! and my full name is !name!
rename !person!.txt !name!.txt
)
pause
This is how I would do it:
#echo off
set "csvpath=C:\Users\user1\OneDrive\Documents\BatchExamples\stuff.csv"
FOR /F "usebackq skip=1 tokens=1,2 delims=," %%g IN (`findstr /v /c:":-:-:" "%csvpath%"`) do (
echo My name is "%%g" and my full name is "%%h"
rename "%~dp0\%%g.txt" "%%h.txt"
)
pause
This code is a bit cleaner and more robust, in that file paths and names can have special characters (like &) without breaking the script.
findstr /v /c:"SEARCHSTRING" "FILEPATH" tells findstr to print every line within FILEPATH excluding (/v) lines with SEARCHSTRING. This doesn't really change much from what you had previously, however it is a bit more robust.
In the rename command, I set it to %~dp0 and then the file name, %~dp0 is the path to where your .bat script is.
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.
I have been expanding on the issue solved here: https://superuser.com/questions/65302/is-there-a-way-to-batch-rename-files-to-lowercase/412413#412413
I wish to change filenames from upper case to lower case and since files are stored in mulitple folders I wish to do it recursively.
I have tried the following:
setlocal EnableDelayedExpansion
CD /D "somefolder"
FOR /D %%G in (*) DO (
FOR /F "Tokens=*" %%f in ('DIR %%G /l/b/a-d') DO (RENAME "%%f" "%%f"))
I get "the system cannot find the path specified errors".
I am sure I am overlooking something obvious.
Your code gives the path error because RENAME cannot find the file. The DIR command lists files in a subdirectory, but your current directory is not the subdirectory.
You have other problems - you are not doing a recursive folder search. The /D option only lists immediate child folders. Your code would miss files in the root "somefolder", as well as any folders that are two or more levels deep.
Also, the original code from SuperUser is flawed. The use of "tokens=*" will strip leading spaces. It is possible (however unlikely) for a file name to begin with a space, and then the code would break. One correct syntax to use is for /f "eol=: delims=" ....
The MichaelS answer using the dir /s option cannot work because the REN command does not accept path information in the target - only the file name and extension can be used. Normally you would solve that problem by using %%~nxF, but that reverts to the original case of the file name!
Here is a proper recursive solution for use on the command line:
for /r "somePath" %D in (.) do #for /f "eol=: delims=" %F in ('dir /l/b/a-d "%D"') do #ren "%D\%F" "%F"
And from a batch script
#echo off
for /r "somePath" %%D in (.) do for /f "eol=: delims=" %%F in ('dir /l/b/a-d "%%D"') do ren "%%D\%%F" "%%F"
If you are willing to go beyond native cmd.exe commands, then another option is my JREN.BAT regular expression renaming utility that supports options to convert names to upper or lower case. It is pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward - no 3rd party exe files needed. Full documentation is built in - accessed from the command line via jren /?, or jren /?? if you want paged output.
With JREN, the recursive solution is as simple as:
jren "^" "" /s /l
You don't need to loop over the subdirectories. Simply add /s to the dir command:
FOR /F "Tokens=*" %%f in ('DIR /l/b/a-d/s') DO (RENAME "%%f" "%%f")
/s will include all subfolders recursively.
I'm trying to figure out how to match folders with a dot in the file name (e.g., ".svn") in a Windows batch script.
Here's the basic script:
setlocal
pushd c:\myDir
#echo off
FOR /D /r %%G in ("*\.whatever") DO (
echo %%G
REM do stuff
)
#echo on
popd
endlocal
This works just fine for most folder names (e.g., "*bin"), but I can't figure out the method to specify a folder with the dot. "*.whatever" and "*\.whatever" return no results. I'm guessing I'm missing some escape character or something equally simple, but I haven't been able to find any documentation on it.
(Before anyone asks, no I'm not trying to recursively delete subversion folders; "*.svn" is just an example.)
Maybe I am missing something, but as you say it seems simple
for /r /d %%a in (.*) do echo %%~fa
But if the folders are hidden, the normal for will not be able to see them, so we need to execute a dir command an process its output with a for /f
for /f "delims=" %%a in ('dir /ad /s /b .*') do echo %%~fa
I have a task assigned to me that I know how to do it other languages, but the Windows batch/cmd requirement has me a little baffled.
There is a directory with several files:
FileName0.txt
FileName0-2014.txt
FileName0-2013.txt
FileName1.txt
FileName1-2014.txt
FileName1-2013.txt
FileName2.txt
FileName2-2014.txt
FileName2-2013.txt
That same pattern might repeat all the way up to FileName54.txt and so on. Also keep in mind I have simplified the examples for various reasons, but the format of the names is the same.
Essentially there are main files (FileName0.txt, FileName1.txt, etc) and then truncated files from earlier (FileName1-2014.txt, FileName1-2013.txt, etc) and each set that number can be anything from 0 to whatever...Highest I've seen is 54 but that could change.
What I need to do is have a batch/cmd file that would keep all the FileName0*.tx files, the main files for the other number sequences (FileName1.txt, FileName2.txt, etc), and then delete all the other truncated files for any of the sequences other than the FileName0 set.
I figured I can focus on the "-" after the sequence number, so basically delete FileName1-*.txt, but trying to figure out a systematic way to make that work for all sequences above 0 is perplexing me.
Thoughts/Comments/Examples?
The ugly way misusing access rights:
attrib +r FileName0*.txt
del FileName*-*.txt
attrib -r FileName0*.txt
The nicer way:
for /L %i in (1,1,999) DO del FileName%i-*.txt
#ECHO OFF
SETLOCAL
FOR %%a IN (filenames*.txt) DO FOR /f "tokens=1,2delims=-" %%s IN ("%%a") DO IF "%%t"=="" SET "keep=%%~na"&GOTO nextstep
:nextstep
ECHO keep %keep%*
FOR %%a IN (filenames*-*.txt) DO FOR /f "tokens=1,2delims=-" %%s IN ("%%a") DO IF "%%s" neq "%keep%" ECHO DEL "%%a"
GOTO :EOF
The required DEL commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO DEL to DEL to actually delete the files.
(I've changed the template to filenameS to suit my testing)
for /f "delims=" %%f in (
'dir /a-d /b *.txt ^| findstr /r /c:"FileName[1-9][0-9]*-"'
) do echo del "%%~ff"
Filter the list of files to retrieve only the required ones.