If I'm on windows 7 and I have a spreadsheet:
1, Ant
2, Brown Bear (note whitespace)
3, Cat
4, Dinosaur
And folders
C:\Directory\1\
C:\Directory\2\
C:\Directory\4\
Is there any way to put in a batch file or a vbs file or whatever the appropriate tool is in that directory that would rename those folders using the spreadsheet? With the final result being:
C:\Directory\1 Ant\
C:\Directory\2 Brown Bear\
C:\Directory\4 Dinosaur\
So far I have a batch file that will append a string to all the folders in the directory it's run in (be cautious where you run it), but I'd just be using if statements for many, many items. Any suggestions on how to connect it to a csv file?
#echo off
for /f "tokens=1,2,* delims=,(" %%a in ('dir /a:d /b') do (
if "%%a" == "10" ( ren "%%a" "%%a Elephant" )
if "%%a" == "11" ( ren "%%a" "%%a Otter")
)
Thanks in advance.
There are a couple unclear points in your question (like the names: are they in a spreadsheet or in a .csv file?) so I made some assumptions. Given a names.csv file with this contents:
1, Ant
2, Brown Bear
3, Cat
4, Dinosaur
The Batch file below achieve the rename you want:
#echo off
setlocal EnableDelayedExpansion
rem Load the array of equivalences from names.csv file:
for /F "tokens=1* delims=," %%a in (names.csv) do set "name[%%a]=%%b"
rem Rename the folders:
cd C:\Directory
for /F "delims=" %%a in ('dir /A:D /B') do ECHO ren "%%a" "%%a!name[%%a]!"
Previous Batch file just show the ren commands; if the output looks good, remove the ECHO part in order to execute the commands.
If names.csv file have a header in the first line, insert "skip=1 " before "tokens" in the first for /F ... command.
Well, if you're OK with using Powershell this little script could help:
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
Import-Csv "D:\Test\ps\look_up.csv" |`
ForEach-Object {
$old = $directorypath + "\" + $_.orig
if(Test-Path($old)){
$newPath = $directorypath + "\" +$_.orig + " " + $_.new
ren $old $newPath
}
}
I had folders named 1,2,3 in the same folder as the script and a csv file with the following content:
orig, new
1, buga boo
2, bla
3, bu
4, none
After running the script the folders were named
Name
----
1 buga boo
2 bla
3 bu
Related
I want to read the file name with the command and automatically move it to the folder with the same name. What should I do?
example:
before processing
after processing
If I have files and folders with the same name, I want to move them to a folder with the same name.
What should I do? Do I have a cmd command?
I will provide both a solution to this exact question, and an alternative that I would suggest to handle this situation.
==========
~ Solution ~
==========
Copy/Paste the code below into an empty file, save, and execute.
#echo off
for /f "tokens=1,* delims=_" %%a in ('dir /b *.xlsx') do (
if not "%%a_%%b"=="%~nx0" (
if not exist %%a mkdir %%a
move "%%a_%%b" "%%a\"
)
)
You can change the "*.xlsx" to any other file extension, or change to "*.*" to work with ANY file extension.
Keep in mind though, this ONLY works with filenames that are formatted like the way you mentioned in your question.
===================
~ Alternative Solution~
===================
I would suggest the Shell Extension "Files 2 Folder" as an alternative. I came across a situation where I needed something similar to what you're asking a couple years ago, and this ended up working out great.
https://www.dcmembers.com/skwire/download/files-2-folder/
Here is another approach using regex in vbscript with a batch file :
#echo off & color 0A
Title Extract Title using Regex in vbscript
SetLocal EnableDelayedExpansion
#for /f "delims=" %%a in ('dir /b *.xlsx') do (
Call :Extract_Title "%%a" Title
If Defined Title (
If Not Exist "!Title!\" MkDir "!Title!\"
Move /-Y "%%a" "!Title!\"
)
)
Pause & Exit
::----------------------------------------------------------------------------------------
:Extract_Title <InputFile> <Title to be Set>
>"%tmp%\%~n0.vbs" (
echo WScript.StdOut.WriteLine Extract_Title(Data^)
echo Function Extract_Title(Data^)
echo Data = Wscript.Arguments(0^)
echo Set re = New RegExp
echo re.Global = True
echo re.IgnoreCase = True
echo re.Pattern = "(\S+|\S.+)_"
echo For Each Match in re.Execute(Data^)
echo Title = Match.SubMatches(0^)
echo Next
echo Extract_Title = Title
echo End Function
)
#for /f "delims=" %%A in ('cscript /nologo "%tmp%\%~n0.vbs" "%~1"') do set "%2=%%A"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
Exit /B
::----------------------------------------------------------------------------------------
Here is my text file:
==================================================
Folder : D:\T\New folder
==================================================
==================================================
Folder : D:\T\Z-Ai
==================================================
==================================================
Folder : D:\T\Z-BiN
==================================================
I need to extract the paths from this file, so I have something like this:
D:\T\New folder
D:\T\Z-Ai
D:\T\Z-BiN
It seems I should use findstr TargetWord TargetFile.txt command. and Also it seems I can use regex like this: findstr /r "^[a-z][a-z]$ ^[a-z][a-z][a-z]$"
But I do not know how to loop through found targets or get the list of output. any help is really appreciated.
Based on your comment, you want to use the result to perform an xcopy task, it seems you really want something like this. Note I used example.txt as input file, and DESTINATION where you should add your destination, including the relevant xcopy switches you require:
#echo off
for /f "tokens=2*" %%i in ('type example.txt ^| findstr /i ":\\"') do xcopy "%%~j\*" DESTINATION
Alternatively we can use the findstr directly on Folder
#echo off
for /f "tokens=2*" %%i in ('type example.txt ^| findstr /i "Folder"') do xcopy "%%~j\*" DESTINATION
You can do like this :
#echo off
Title Extract list of path in a file using batch script
set "TxtList=MyList.txt"
Set "OutPutData=Output.txt"
Call :Extract "%TxtList%" "%OutPutData%"
Start "" "%OutPutData%"
Exit
::*****************************************************
:Extract <InputData> <OutPutData>
(
echo Data = WScript.StdIn.ReadAll
echo Data = Extract(Data,"[\w]:(\\[0-9\sA-Za-z\-]*)+"^)
echo WScript.StdOut.WriteLine Data
echo '************************************************
echo Function Extract(Data,Pattern^)
echo Dim oRE,oMatches,Match,Line
echo set oRE = New RegExp
echo oRE.IgnoreCase = True
echo oRE.Global = True
echo oRE.Pattern = Pattern
echo set oMatches = oRE.Execute(Data^)
echo If not isEmpty(oMatches^) then
echo For Each Match in oMatches
echo Line = Line ^& Trim(Match.Value^) ^& vbcrlf
echo Next
echo Extract = Line
echo End if
echo End Function
echo '************************************************
)>"%tmp%\%~n0.vbs"
cscript /nologo "%tmp%\%~n0.vbs" < "%~1" > "%~2"
If Exist "%tmp%\%~n0.vbs" Del "%tmp%\%~n0.vbs"
exit /b
::****************************************************
For Windows. you can use powershell.
select-string -Path c:\tmp\file.txt -Pattern '[A-Z]:(\\[0-9\ A-Za-z\-]*)+' -AllMatches | % { $_.Matches } | % { $_.Value }
In my opinion, For /F is all you need for the task. Although using Type may be useful in some situations, there's no need to use find.exe or findstr.exe for this task as you don't need to match a particular glob/pattern:
#For /F "EOL==Tokens=2*UseBackQ" %%A In ("TargetFile.txt")Do #"%__AppDir__%xcopy.exe" "%%B" "Destination\" /Options
Please note that it may be wise, if there's a chance that one or more of theses Folders do not exist, that you prepend using If Exist "%%B\". Importantly, if each of the lines containing the Folder paths, is space padded up to the end of its line, this solution will not work for you.
I have a script which can list all files under a folder and its subforlders, with some properties such as path, file name, modified date and size. But, I can't add one extra property, file owner.
#ECHO off
SET v1=%%~dpF
SET v2=%%~nxF
SET v3=%%~zF
(for /r %%F in (*) do #echo "%v1%","%v2%",%v3%) > test.csv
PAUSE
Basically I want to add a 4th parameter, which should show file owner. It is in Windows 7 environment.
You can use the dir command with the /q switch to include the owner of each file.
#ECHO OFF
SetLocal EnableDelayedExpansion
for /r %%a in (*) do for /f "tokens=5" %%b in ('dir /q "%%~fxa" ^| findstr "%%~nxa"') do (
echo "%%~dpa","%%~nxa","%%~za","%%b"
) >> test.csv
This will always append to test.csv, if you want to always recreate test.csv you can encase your entire for loop in parenthesis (as you had);
#ECHO OFF
SetLocal EnableDelayedExpansion
(for /r %%a in (*) do for /f "tokens=5" %%b in ('dir /q "%%~fxa" ^| findstr "%%~nxa"') do (
echo "%%~dpa","%%~nxa","%%~za","%%b"
)) > test.csv
Not exactly what you asked for, but I adapted a PowerScript to show what you ask for. Just update the PARAM section with your file and folder names, copy and paste into PowerShell and hit enter twice:
PARAM (
$Path = 'C:\Users\PATHHERE\',
$report = 'C:\Users\USERNAME\Desktop\OUTPUTFILENAMEHERE.csv'
)
$LastWrite = #{
Name = 'Last Write Time'
Expression = { $_.LastWriteTime.ToString('u') }
}
$Owner = #{
Name = 'File Owner'
Expression = { (Get-Acl $_.FullName).Owner }
}
$HostName = #{
Name = 'Host Name'
Expression = { $env:COMPUTERNAME }
}
Get-ChildItem -Recurse -Path $Path |
select $HostName, $Owner, Name, Directory, $LastWrite, Length |
Export-Csv -NoTypeInformation $Report
This script adapted from info found here. I find batch files to be more and more trouble to deal with these days, and PowerShell is very flexible. The guys over at serverfault.com will no doubt be able to help you better with these kinds of questions.
is there a way to transfer characters in the a plain .txt file.
I have a lot of entries in the .txt file and they are all in this format:
1 = Example,
2 = Example2,
3 = Example3...
what I need is a batch file to transfer "# =" to the right side of the string. So it looks like this:
Example = 1,
Example2 = 2...
Is it possible to that with a .bat file?
This will handle more than one word where you have Example...
#echo off
for /f "tokens=1,* delims== " %%a in (input.txt) do >>output.txt echo %%b = %%a
If you can use GNU sed:
sed "s/\(\S\+\)\s=\s\(\S\+\)/\2 = \1/" file
Something like this should work:
#echo off
pushd "C:\some\where"
for /f "tokens=1,2 delims==" %%a in (input.txt) do echo %%b = %%a
popd
Or use this to get rid of whitespace:
#echo off
setlocal EnableDelayedExpansion
pushd "C:\some\where"
for /f "tokens=1,2 delims==" %%a in (input.txt) do (
set "key=%%a"
set "val=%%b"
echo !val: =! = !key: =!
)
popd
To save the output to a file, call either script like this:
switch.cmd >output.txt
I have to rename a bunch of files. They're all in the same folder. My idea was to do this by a batch script, but the problem is, that I have to "split" the original filename and give it an indexing number.
For example:
Original Filename: XYZ SomeDocument.docx
New Filename: XYZ 01 SomeDocument.docx
Does anybody have an idea how I can do this?
#echo off
setlocal EnableDelayedExpansion
set index=100
for /F "tokens=1*" %%a in ('dir /B /A-D') do (
set /A index+=1
ren "%%a %%b" "%%a !index:~-2! %%b"
)
I always use Python for tasks like this :)
Eg:
import os
DIR = r'C:\foo'
index = 1
for file_name in os.listdir(DIR):
old_path = os.path.join(DIR, file_name)
split = file_name.split("XYZ")
new_file_name = "XYZ %s %s" % (index, split[1].strip())
new_path = os.path.join(DIR, new_file_name)
os.rename(old_path, new_path)
index += 1