extract second last Substring in bat file - batch-file

I am trying to get the substring which lies between the last & second last fullstop (.) in a filename using the batch file, filename can have any number of fullstops. The file name will look like as follows, in this particular example output should be '8'.
filename: a_b_c_d_e.1.2.3.4.5.6.7.8.9
I tried the below part, but it always outputs the string after the first fullstop i.e 1.2.3.4.5.6.7.8.9 instead of '8'.
set "string=a_b_c_d_e.1.2.3.4.5.6.7.8.9"
#echo %string:*.=%
pause
Any working suggestions can be helpful.

You could use the file modifier syntax.
Replace all dots with backslashes and then take the parent directory by appending \..
#echo off
set "string=a_b_c_d_e.1.2.3.4.5.6.7.8.9"
for /F "delims=" %%X in ("%string:.=\%\..") do echo %%~nX

Related

Batch Script – Delete Characters in a String till delimiter

I am desperately looking for a solution to the following problem:
I have a batch file that reads a path from a txt file and saves it as a string. For example: pathname=C:\User\Software\v1.1\Test\abcdefg
Now I just want to get the path and delete everything from the last "\". So a folder above the final folder in the path:
result=C:\User\Software\v1.1\Test
I have a hard time with batch scripts, I hope you can help me.
set result=%pathname:*\=%
This deletes the chars befor the first "\": User\Software\v1.1\Test\abcdefg
Is there a way to give back every char before the last "\" like: C:\User\Software\v1.1\Test
The paths will differ in length everytime.
#ECHO OFF
SETLOCAL
SET "pathname=C:\User\Software\v1.1\Test\abcdefg"
for %%e in ("%pathname%") do set "result=%%~dpe"
SET "result=%result:~0,-1%"
ECHO +%result%+
GOTO :eof
Treating the pathname as though it was a filename.
The + at either end of the report shows there are no extra spaces in the result.

Find String in log files, and copy whole line into a new file

Good Day All.
I have a bunch of log files that contains a certain folder in a folder path, that is "/input", that is part of a pathname that varies - "/input" being the only constant here...
How do you scan all the log files (*.log), look for all sub-string instances of "/input" and write the whole line, containing this part of the path, that is "/input", to a new text file?
Example of one line in a log file:
2014-01-16 00:33:57 10.0.1.169 ddca 192.168.34.11 21 CWD /DDAA/Input/ 250 0 0
How do I write all the lines, containing this part "/input" to a new text file?
Thanks.
#echo off
setlocal enableextensions
set "source=c:\where\the\log\files\are"
set "target=c:\output\folder\newFile.log"
pushd "%source%"
(for /f "tokens=1,* delims=:" %%a in ('findstr /i /l /c:"/input/ " "*.log"') do (
echo(%%b
)) > "%target%"
popd
Search for the string using findstr. It will return a string containing the file name where the string was found, followed by a colon and the full line in the log file. Then, using for command this line is splitted using the colon as a delimiter and the right part of the line (the original line in log file) is echoed. The output of the for command is then redirected to the final file.
pushd and popd are used to ensure that references to the log files, and the names in the output of the findstr command, does not contain aditional colons that interfere in the splitting part.
findstr /i /c:"/input" *.log >output.txt
The /i switch makes the search case insensitive. The /c: switch is used so that the leading / is not treated as a switch indicator.
Because a wildcard was used, it will prefix each line with the name of the file, followed by a colon, like in the following
filename.log:2014-01-16 00:33:57 10.0.1.169 ddca 192.168.34.11 21 CWD /DDAA/Input/ 250 0 0
Lots of options. You can create a small tool that does this for you, but my guess is somebody somewhere already done this. Did you google for something like this?
If you are up to some manual work, I know Notepad++ has the functionality to search through txt-files in folder(s) matching a (sub)string.
Also relevant:
https://superuser.com/questions/110350/how-to-use-notepad-to-find-files-in-a-directory-that-do-not-contain-string

Use Dos commands to copy file and preserve date in file name

I'm having trouble trying to copy and rename a file using only dos commands. I have a file of the format myfile20130218 and want to copy and rename it to some_other_file_20130218.
I know I can use copy source dest but I'm having trouble with how to isolate the date and preserve it. I cannot guarantee that he date will be today's date so that is ruled out, the source file will always be the same name.
I can run either a series of commands or a batch script, but thing that that I am currently having trouble with, is after I find a match that I need to copy, using myfile????????, how can I now get those file names to pull the dates off them?
EDIT: for clarification I will be looking at files in a known directory, as above, I will know the format of the file name, and will only be checking a specific directory for it. The process that checks the directory is a ConnectDirect file watcher, so when a file is found matching myfile20130218 I can fire off some commands, but don't know how to check the directory and get the name of the file present.
Something like this should work:
%oldname:~-8% extracts the last 8 characters from %oldname% which are then appended to the new filename.
Update: If you can identify the file with an external program and then call the batch script with the file name
copyfile.cmd C:\path\to\myfile20130218
you could do something like this:
set oldname=%~nx1
set newname=%~dp1some_other_file_%oldname:~-8%
copy "%~f1" "%newname%"
Update 2: If you know folder and the format you could call the script with the folder
copyfile.cmd C:\folder
and do something like this:
#echo off
setlocal EnableDelayedExpansion
for /f %%f in (
'dir /b "%~f1" ^| findstr /r "myfile[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$"'
) do (
set oldname=%~f1\%%f
set newname=%~f1\my_other_name_!oldname:~-8!
copy "!oldname!" "!newname!"
)
endlocal
Edit: Script breakdown.
setlocal EnableDelayedExpansion enables variable expansion inside loops and conditionals.
for /f %%f in ('...') executes the command between the single quotes and then loops over the output of that command.
dir /b "%~f1" lists the content of the given directory (%~f1 expands to the full path of the first argument passed to the script) in simple mode (no header, no summary).
findstr /r "myfile[0-9]...[0-9]$" filters the input for strings that end with the substring "myfile" followed by 8 digits. The circumflex before the pipe (^|) escapes the pipe, because otherwise it would take precedence over the for command, which would effectively split the for command in half, resulting in an invalid command-line.
set oldname=%~f1\%%f assign the full path to a matching file to the variable oldname.
set newname=%~f1\my_other_name_!oldname:~-8! assign the full path to the new filename ("my_other_name_" followed by the trailing 8 digits from oldname) to the variable newname.
copy "!oldname!" "!newname!" I don't need to explain this, do I?

It is possible to use a batch file to read a line and then use only a substring of that line to perform a command?

I am working with ClearCase and I would like to use a batch script to run through a text file generated through cleartool commands, copy a file specified in the line, but then perform a rename by only extracting a substring up until a specified set of characters.
An example text file is:
"M:\LEVEL1\PROJECT\src\ROOT\file 2.txt##\main\LEVEL1\5"
"M:\LEVEL1\PROJECT\src\ROOT\file 1.txt##\main\LEVEL1\3"
"M:\LEVEL1\PROJECT\src\ROOT\folder 1\file 5.txt##\main\LEVEL1\2"
"M:\LEVEL1\PROJECT\src\ROOT\file 4.txt##\main\LEVEL1\3"
"M:\LEVEL1\PROJECT\src\ROOT\file 7.txt##\main\LEVEL1\2"
What I would like to do is create a command that looks like this (using the first line):
xcopy "M:\LEVEL1\PROJECT\src\ROOT\file 2.txt##\main\LEVEL1\5" "<output folder>\LEVEL1\PROJECT\src\ROOT\file 2.txt"
where <output folder> is a folder that is specified as a parameter when running the script. So basically what I am asking for is to extract only what lies between M: and ## in each line as it is read so I can use it in a copy command.
I already have xcopy "%%~fA" "%OUTPUTDIR:"=%\%%~pnxA" which copies a line to an output directory but the %%~pnxA will only remove the drive letter and not remove the remaining part of the line from ## onwards.
Is this possible?
Just breaking up JJRythms answer into an explanation.
for /F "tokens=1,2,3 delims=:#" %%A in (in.txt) do xcopy %%A:%%B##%%C DIR:%%B
The purpose of this statement is to parse the lines in the in.txt file and then use the pieces we want.
for - the loop command.
/F - the File parsing loop type option.
tokens=1,2,3 - the sub-strings in which to retrieve based upon the string delimiters.
delims=:# - the delimiters which separate the tokens. (Default is spaces)
%%A - the starting loop variable. (Token 1 = %%A, Token 2 = %%B, Token 3 = %%C)
in (in.txt) the file in which to perform the loop command.
do - the commands to perform for each line of the file.
Example Using the first line.
"M:\LEVEL1\PROJECT\src\ROOT\file 2.txt##\main\LEVEL1\5"
Is parsed as:
%%A = "M
%%B = \LEVEL1\PROJECT\src\ROOT\file 2.txt
%%C = \main\LEVEL1\5"
The delimiters are consumed and therefore removed from the resulting variables.
Note that this solution will not work if there are any # signs anywhere else in the file name.
Type for /? on the command line for help and options.

Bat file find folder of file

So my many attempts to search for a solution have resulted in a million ways to find the folder of the bat file being executed, however what I am looking to do is find the folder for the filename being passed to the bat file.
Example:
C:\Temp\runthis.bat "C:\Blah\Ah Argh\rage.txt"
I want to get a string within that bat file that is simply "C:\Blah\Ah Argh\", alternatively I would also be able to work with getting a string of "rage.txt"
Editing to explain why: Looking to check for the filename within another txt file which is the directory listing of a ftp server to verify that a file successfully uploaded to it. Then if successful I need to move the file to a subfolder of the original folder \uploaded\ but we have many of these folders setup so I can't hard code it.
Thanks
#echo off
The file path is %~dp1
The file name is %~nx1
The parameter modifiers are the same as for FOR variables.
Type 'HELP CALL' from a command prompt for a full list of parameter modifiers.
#echo off
if %1X==X echo Syntax: %0 "path"
rem The for loop doesn't actually loop. You can split strings with it, but in
rem this case we don't. So there is only one iteration in which %%X will
rem contain the full path.
rem Pass it %1, which is the first parameter. Note the quotes, which are
rem required if you don't add quotes around the parameter and optional (but
rem still valid) when you do.
for /F "delims=|" %%X in ("%1") do (
rem FOR LOOP variables can be used with certain modifiers, preceeded by a
rem tilde. In this case I'm using d and p, which stand for drive and path,
rem effectively trimming the file name from the path.
echo %%~dpX
rem The ~n modifier selects the file name only. ~x is for extension
echo %%~nxX
)

Resources