File name with vbs scripts - vbscript

I want to add a charecter file name.
For Example
123456.jpg --> 1234506.jpg
ABCDEF.jpg --> ABCDE0F.jpg
orginal file 6 charecters new file name 7 charecter (I want to add 0 for all file name Please attention after 0 character has a character.)
for this proccessbatch file or vbs
Regards,

#echo off
setlocal enableextensions disabledelayedexpansion
for /f "delims=" %%a in (
'dir /b /a-d ^|
findstr /r /b
/c:"[^.][^.][^.][^.][^.][^.]\."
/c:"[^.][^.][^.][^.][^.][^.]$"
'
) do (
set "fileName=%%a"
setlocal enabledelayedexpansion
for %%b in ("!filename:~0,5!0!filename:~5!") do endlocal & if not exist "%%~b" echo ren "%%a" "%%~b"
)
This uses dir command to retrieve the list of files and findstr to filter and only get the files with 6 characters in filename. For each file found, the file name is retrieved into a variable, and substring operation is done to compose the new name.
To avoid problems with exclamations in file names, we need to have delayed expansion enabled to read the variable, but disabled to execute the command. This is the reason for the second for, enable delayed expansion, read the required value and store it inside the for command replaceable parameter, disable delayed expansion and now, without problem with exclamations, execute the required command.
The ren command is only echoed to console. If the output is correct, remove the echo to execute the rename operation

Here's how it can be done with VBScript and a FileSystemObject. This script will need to be in the same folder as your files. Otherwise, you'll have to use the full path to your files.
' Files to update...
a = Array("123456.jpg", "ABCDEF.jpg")
With CreateObject("Scripting.FileSystemObject")
For i = 0 To UBound(a)
' Change name. Use first 5 chars, plus "0", plus rest...
.GetFile(a(i)).Name = Left(a(i), 5) & "0" & Mid(a(i), 6)
Next
End With

Related

loop through a folder with special characters in the folder name

I'm trying to write a batch file to move files from a folder into another folder. The folder has a special character in the name. I can't change that name.
Here is my script
set "MM=%Date:~4,2%"
set "DD=%Date:~7,2%"
set "thisDate=%MM%%DD%"
set baseDir="T:\R ^& D files received"
set backupDir=%baseDir%\2022\%thisDate%
if not exist "%backupDir%\NUL" mkdir "%backupDir%"
for %%f in ("%baseDir%\*.pdf") do (
echo %%f
move %%f "%backupDir%\%%f")
This is not working. I get
R
&
D
files
received\*.pdf
No file is moved.
Any idea or help is appreciated.
#ECHO OFF
SETLOCAL
SET "thisdate=0419"
set "baseDir=U:\R & D files received"
set "backupDir=%baseDir%\2022\%thisDate%"
if not exist "%backupDir%\NUL" mkdir "%backupDir%"
for %%f in ("%baseDir%\*.pdf") do (
echo "%%f"
move "%%f" "%backupDir%\%%~nxf" >nul
)
DIR /s "%basedir%"
GOTO :EOF
Intriguingly. you've used the set "var=value" format for setting thisdate but not for the directory names. I've used a constant for thisdate as I use a YYYYMMDD date format.
Also, my test drive is U:, not T:.
Tips : Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \, space or quotes - build pathnames from the elements - counterintuitively, it is likely to make the process easier.
Your for %%f resolved to for %%f in (""T:\R ^& D files received"\*.pdf") do ( hence the strange result.
Note that %%f contains the full pathname to the .pdf files - which includes spaces. Hence you need to "quote the sourcefile name" and use just the name and extension of that file (%%~nxf) concatenated onto the backupdirectoryname string with separator - all of which again contains a space and hence needs to be quoted.
>nul appended to suppress 1 file(s) moved messages.

Windows Batch file - strip leading characters

I have a batch file which copies some local files up to a google storage area using the gsutil tool. The gsutil tool produces a nice log file showing the details of the files that were uploaded and if it was OK or not.
Source,Destination,Start,End,Md5,UploadId,Source Size,Bytes Transferred,Result,Description
file://C:\TEMP\file_1.xlsx,gs://app1/backups/file_1.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.804000Z,CPHHZfdlt6AePAPz6JO2KQ==,,18753,18753,OK,
file://C:\TEMP\file_2.xlsx,gs://app1/backups/file_2.xlsx,2018-12-04T15:25:48.428000Z,2018-12-04T15:25:48.813000Z,aTKCOQSPVwDycM9+NGO28Q==,,18753,18753,OK,
What I would like to do is to
check the status result in column 8 (OK or FAIL)
If the status is OK then move the source file to another folder (so that it is not uploaded again).
The problem is that the source filename is appended with "file://" which I can't seem to remove, example
file://C:\TEMP\file_1.xlsx
needs to be changed into this
C:\TEMP\file_1.xlsx
I am using a for /f loop and I am not sure if the manipulation of the variables %%A is different within a for /f loop.
#echo off
rem copy the gsutil log file into a temp file and remove the header row using the 'more' command.
more +1 raw_results.log > .\upload_results.log
rem get the source file name (column 1) and the upload result (OK) from column 8
for /f "tokens=1,8 delims=," %%A in (.\upload_results.log) do (
echo The source file is %%A , the upload status was %%B
set line=%%A
set line=!line:file://:=! >> output2.txt echo !line!
echo !line!
)
The output is like this.
The source file is file://C:\TEMP\file_1.xlsx , the upload status was OK
The source file is file://C:\TEMP\file_2.xlsx , the upload status was OK
I'm expecting it to dump the altered values out into a new file but it is not producing anything at the moment.
Normally I would extract from a specific character to the end of the string with something like this but it doesn't work with my For/f loop.
%var:~7%
Any pointers or a different way of doing it greatly appreciated.
Since the part to remove seems fixed it is easier to use substrings.
Also using for /f "skip=1" evades he neccessity of the external command more +1 and another intermediate file.
#echo off & setlocal EnableDelayedExpansion
type NUL>output2.txt
for /f "skip=1 eol=| tokens=1,8 delims=," %%A in (.\upload_results.log) do (
echo The source file is %%A , the upload status was %%B
set "line=%%A"
set "line=!line:~7!"
echo(!line!>>output2.txt
echo(!line!
)
File names and paths can contain also one or more exclamation marks. The line set line=%%A is parsed by Windows command processor a second time before execution with enabled delayed expansion. See How does the Windows Command Interpreter (CMD.EXE) parse scripts? Every ! inside the string assigned to loop variable A is on this line interpreted as begin or end of a delayed expanded environment variable reference. So the string of loop variable A is assigned to environment variable line with an unwanted modification if file path/name contains one or more exclamation marks.
For that reason it is best to avoid usage of delayed expansion. The fastest solution is for this task using a second FOR to get file:// removed from string assigned to loop variable A.
#echo off
del output2.txt 2>nul
for /F "skip=1 tokens=1,8 delims=," %%A in (upload_results.log) do (
echo The source file is %%A , the upload status was %%B.
for /F "tokens=1* delims=/" %%C in ("%%~A") do echo %%D>>output2.txt
)
Even faster would be without the first echo command line inside the loop:
#echo off
(for /F "skip=1 delims=," %%A in (upload_results.log) do (
for /F "tokens=1* delims=/" %%B in ("%%~A") do echo %%C
))>output2.txt
The second solution can be written also as single command line:
#(for /F "skip=1 delims=," %%A in (upload_results.log) do #for /F "tokens=1* delims=/" %%B in ("%%~A") do #echo %%C)>output2.txt
All solutions do following:
The outer FOR processes ANSI (fixed one byte per character) or UTF-8 (one to four bytes per character) encoded text file upload_results.log line by line with skipping the first line and ignoring always empty lines and lines starting with a semicolon which do not occur here.
The line is split up on every occurrence of one or more commas into substrings (tokens) with assigning first comma delimited string to specified loop variable A. The first solution additionally assigns eighth comma delimited string to next loop variable B according to ASCII table.
The inner FOR processes the string assigned to loop variable A with using / as string delimiter to get assigned to specified loop variable file: and to next loop variable according to ASCII table the rest of the string after first sequence of forward slashes which is the full qualified file name.
The full qualified file name is output with command echo and appended either directly to file output2.txt (first solution) or first to a memory buffer which is finally at once written into file output2.txt overwriting a perhaps already existing file with that file name in current directory.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
for /?
See also the Microsoft article about Using command redirection operators for an explanation of the redirections >, >> and 2>nul

Creating input subfolder structure inside output folder

I have a batch script that:
read input files from a folder
elaborate them
store output files in another folder
Example code:
set pathTmp=D:\a\b\c
set pathIn=%pathTmp%\in
set pathOut=%pathTmp%\out
for /f %%i in ('dir /b %pathIn%') do (
java XXX.jar %pathIn%\%%i >> %pathOut%\%%i
)
Now I'd like to modify it to read files from all subfolders of pathIn and put the output file in the same subfolder but under pathOut.
Example: if input file is in pathIn\zzz, the output file must be in pathOut\zzz.
How can I recreate the input subfolder structure inside output folder?
I would use xcopy together with the /L switch (to list files that would be copied) to retrieve the relative paths. For this to work, you need to change to the directory %pathIn% first and specify a relative source path (for this purpose, the commands pushd and popd can be used).
For example, when the current working directory is D:\a\b\c\in and its content is...:
D:\a\b\c\in
| data.bin
+---subdir1
| sample.txt
| sample.xml
\---subdir2
anything.txt
...the command line xcopy /L /I /S /E "." "D:\a\b\c\out" would return:
.\data.bin
.\subdir1\sample.txt
.\subdir1\sample.xml
.\subdir2\anything.txt
3 File(s)
As you can see there are paths relative to the current directory. To get rid of the summary line 3 File(s), the find ".\" command line is used to return only those lines containing .\.
So here is the modified script:
set "pathTmp=D:\a\b\c"
set "pathIn=%pathTmp%\in"
set "pathOut=%pathTmp%\out"
pushd "%pathIn%"
for /F "delims=" %%I in ('xcopy /L /I /S /E "." "%pathOut%" ^| find ".\"') do (
md "%pathOut%\%%I\.." > nul 2>&1
java "XXX.jar" "%%I" > "%pathOut%\%%I"
)
popd
Additionally, I placed md "%pathOut%\%%I\.." > nul 2>&1 before the java command line so that the directory is created in advance, not sure if this is needed though. The redirection > nul 2>&1 avoids any output, including error messages, to be displayed.
I put quotation marks around all paths in order to avoid trouble with white-spaces or any special characters in them. I also quoted the assignment expressions in the set command lines.
You need to specify the option string "delims=" in the for /F command line, because the default options tokens=1 and delims=TABSPACE would split your paths unintentionally at the first white-space.
Note that the redirection operator >> means to append to a file if it already exists. To overwrite, use the > operator (which I used).
You could do something like this:
#setlocal EnableDelayedExpansion
#echo off
set pathTmp=D:\a\b\c
set pathIn=%pathTmp%\in
set pathOut=%pathTmp%\out
REM set inLength=ADD FUNCTION TO CALCULATE LENGTH OF PATHIN
for /f %%i in ('dir /b /s %pathIn%') do (
set var=%%i
java XXX.jar %%i >> %pathOut%\!var:~%inLength%!
)
This will strip the length of the pathIn directory from the absolute path leaving only the relative path. Then it appends the relative path onto the pathOut var
You would need to find or write a function to get the length of the the pathIn string. Check out some solutions here.

Batch file to process csv document to add space in postcode field

I have a csv file populated with name, address, and postcode. A large number of the postcodes do not have the required space in between e.g LU79GH should be LU7 9GH and W13TP should be W1 3TP. I need to add a space in each postcode field if it is not there already, the space should always be before the last 3 characters.
What is the best way to solve this via windows command line?
Many Thanks
You can do this with for /f as follows:
#echo off
setlocal enabledelayedexpansion
if "%~1" equ "" (echo.%~0: usage: missing file name.& exit /b 1)
if "%~2" neq "" (echo.%~0: usage: too many arguments.& exit /b 1)
for /f %%i in (%~1) do (echo.%%i& goto :afterheader)
:afterheader
for /f "skip=1 tokens=1-3 delims=," %%i in (%~1) do (
set name=%%i
set address=%%j
set postcode=%%k
set postcode=!postcode: =!
echo.!name!,!address!,!postcode:~0,-3! !postcode:~-3!
)
exit /b 0
Demo:
> type data.csv
name,address,postcode
n1,a1,LU79GH
n2,a2,W13TP
n1,a1,LU7 9GH
n2,a2,W1 3TP
> .\add-space.bat data.csv
name,address,postcode
n1,a1,LU7 9GH
n2,a2,W1 3TP
n1,a1,LU7 9GH
n2,a2,W1 3TP
You can redirect the output to a file to capture it. (But you can't redirect to the same file as the input, because then the redirection will overwrite the input file before it can be read by the script. If you want to overwrite the original file, you can redirect the output to a new file, and then move the new file over the original after the script has finished.)
Using windows you could do something with Powershell.
$document = (Get-Content '\doc.csv')
foreach($line in $document) {
Write-Host $line
// Add logic to cut out exactly what column your looking at with
$list = $line -split","
// Then use an if statement and regular expression to match ones with no space
if($list[0] -match ^[A-Z0-9]$){
// item has no space add logic to add space and write to file
}else{
// item has space or doesnt match the above regular expression could skip this
}
}
Pretty good documentation online check out http://ss64.com/ps/ for help with powershell.
Parsing CSV can be tricky because a comma may be a column delimiter, or it may be a literal character within a quoted field.
Since your postcode is always the last field, I would simply look at the 4th character from the end of the entire line, and if it is not already a space, than insert a space before the last 3 characters in the line. I will also assume that the first line of the file lists the field names, so you don't want to modify that one.
Using pure batch (assuming no values contain !):
#echo off
setlocal enableDelayedExpansion
set "skip=true"
>"test.csv.new" (
for /f "usebackq delims=" %%A in ("test.csv") do (
set "line=%%A"
if "!line:~-4,1!" equ " " set "skip=true"
if defined skip (echo !line!) else (echo !line:~0,-3! !line:~-3!)
set "skip="
)
)
move /y "test.csv.new" "test.csv" >nul
The solution is simpler if you use my JREPL.BAT regular expression text processor. It is a pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward. The following one liner will do the trick:
jrepl "[^ ](?=...$)" "$& " /jbegln "skip=(ln==1)" /f test.csv /o -
Use CALL JREPL ... if you use the command within another script.

File path in Windows XP NTFS Format with batch for /F command

i try to figure out if i recognize enough reading the help and support center with this question.
Some informations are not linked in a for me reasonable way.
Reading about the Type command it was possible for me to recognize that using NTFS Format with my hard disk ,i have to use double quotes for path and file names with spaces.
I will show a batch code first without quotes and then with ,because with a for /F command this case double quoted do not match either with a echo command nor a type command.
#echo off
rem #
rem #
rem #
for /F %%A in (Textdokument.txt) do set Datei=%%A
rem #
rem #
echo %Datei%
rem #
rem #
echo.
rem #
rem #
set Datei=
rem #
rem #
pause
Workes proper.
The same example with double quotes just returns a ,file not found message.
for /F %%A in ("Dokumente und Einstellungen"\Benutzername\Desktop^\"Neuer Ordner"\Textdokument.txt) do set Datei=%%A
Building an easy base for gathering more reasonable file content leads to this question regarding all information i have read. To search further i would be lucky with a answer.
Best wishes
for /f %%a in (someFileName) ... will consider someFileName as a file name to read, executing the code in the do clause for each of the lines in the file.
for /f %%a in ("some file name") .... will consider "some file name" as a inmediate string to process, executing the code in the do clause for only this string.
for /f "usebackq" %%a in ("some file name") ... will consider "some file name" as a file name to read, executing the code in the do clause for each of the lines in the file.
And, the quotes should enclose the full path, so your code should be
for /F "usebackq" %%A in (
"Dokumente und Einstellungen\Benutzername\Desktop\Neuer Ordner\Textdokument.txt"
) do set Datei=%%A
Try like this with the full path and with just a " at start and one at the end and using type:
for /F %%A in (type "c:\Dokumente und Einstellungen\Benutzername\Desktop\Neuer Ordner\Textdokument.txt") do set Datei=%%A

Resources