Extracting string after last instance of delimiter in a Batch file - string

I'm working on writing a Windows batch file that is called by a Java program. A number of different strings denoting file directories are passed into the batch file as parameters. I am trying to figure out how to extract a string after the last instance of the "\". For example, I have three directories:
C:\Users\owner\Documents
C:\Users\owner\Videos
C:\Users\owner\Pictures\Trip
I would like to split it so that the strings become:
Documents
Videos
Trip
How would you guys suggest I do this?
EDIT: A follow-up question has been asked here: For loop in Windows batch file: Error: "The syntax of the command is incorrect"

After assigned one parameter to "param" variable, use:
for %%a in (%param:\= %) do set lastDir=%%a
This method works as long as the last directory does NOT have spaces. This detail may be fixed, if needed. The processing of all parameters would be like this:
:nextParam
set "param=%~1"
if not defined param goto endParams
for %%a in (%param:\= %) do set lastDir=%%a
echo Last dir: %lastDir%
shift
goto nextParam
:endParams
Or, in a simpler way (with no spaces restrictions):
:nextParam
if "%~1" equ "" goto endParams
echo Last dir: %~N1
shift
goto nextParam
:endParams

If the strings are passed as arguments 1-3. you can use %~n1, %~n2, %~n3 to get the last folder in the path.

Related

Windows CMD expand filename if file has .double.extension

I'm writing a script that converts a Markdown file to a PDF, facilitated by Pandoc.
So if you drag C:\Users\User\Documents\English\PAPER1.md onto the script, it'll create C:\Users\User\Documents\English\PDFs\PAPER1.pdf.
This is achieved in the header of the script via
set INPUT=%1
set PDFDIR=%~dp1\PDFs
set PDF=%PDFDIR%\%~n1.pdf
However, in certain circumstances, the input filename will be Something.md.txt, in which case I only still want to output Something.pdf. (Removing more than three extensions will probably not be necessary or desirable.)
But the current setup only strips one extension, producing Something.md.pdf.
However, %~nn1.pdf does not work, nor does set p=%~n1 set PDF=%~np, giving
The following usage of the path operator in batch-parameter
substitution is invalid: %~np
How do I get the bare filename of a file with "two extensions"?
I'd change every line from the provided header of the script to:
Set "INPUT=%~1"
Set "PDFDIR=%~dp1PDFs"
For %%A In ("%~dpn1") Do Set "PDF=%PDFDIR%\%%~nA.pdf"
Because there's no surety of the input content, please use best practice and always reference these variables wherever possible using doublequotes:
Echo "%INPUT%"
Echo "%PDFDIR%"
Echo "%PDF%"

left string in a batch file

I am writing a .bat file in which I'm trying to compare the last modified date of a file with the system date (date-only, not the time). To get the last modified date of the file, I use the following:
for %%? in ("anyFile.png") do set dat=%%~t?
This gives me the last modified date and time of the file (dat=31.08.2016 08:59). Now I try to cut the string to get only the ten characters in the beginning (31.08.2016):
set dat=%dat:~0,10%
If I type the code directly into the console it works like a charm, but in my batch file the console output only gives me the following:
dat=~0,10
I don't have a clue what I'm missing, and in the internet I couldn't find anyone with a similar problem neither.
Thank you #aschipfl for the hint, the problem with the dat variable could be solved with delayed expansion:
Setlocal EnableDelayedExpansion
...
if exist "anyFile.png" (
for %%? in ("anyFile.png") do set dat=%%~t?
set dat=!dat:~0,10!
)
#geisterfurz007: no, this was not the whole code. But as the problem is solved now, I think there is no need for it anymore. :)

Batch Script - Comma causing problems when writing numerical value to txt file

So this is an example of a script I'm writing to produce txt file containing a list of correctly formatted commands to be passed to another system, based on a long series of questions.
If objectName, objectNumber, or objectCategory are assigned an alphanumeric value, the script will write correctly to the txt file. However, if I were to assign a numerical value, the value is not written to the txt file.
I'm guessing this is a syntax issue related to the use of a comma, as I can replace it with with pretty much anything and the script will behave, though unfortunately it has to be a comma.
#ECHO OFF
SET objectCounter=1
SET /p objectName=What is the name of the object %objectCounter%?:
#ECHO OBJECTNAME%objectCounter%,%objectName%> objects.txt
SET /p objectNumber=How many of object %objectCounter% are there?:
#ECHO OBJECTNUMBER%objectCounter%,%objectNumber%>> objects.txt
SET /p objectCategory=Which group does object %objectCounter% belong to?:
#ECHO OBJECTCATEGORY%objectCounter%,%objectNumber%>> objects.txt
This is an example of the output to the txt file if objectNumber is assigned a value of 1:
OBJECTNAME1,Apple
OBJECTNUMBER1,
OBJECTCATEGORY1,Fruit
And this is an example of the output to the txt file if objectNumber is assigned a value of 2 or more:
OBJECTNAME1,Apple
OBJECTCATEGORY1,Fruit
This is a simplification: a echo command to send the text data 1 to a file:
echo data 1>somewhere.txt
Here it is easy to see that the 1 will be handled by the parser as the stream number to redirect, not data to send to the file.
But the question is not using a space, but a comma. Why the same behaviour? Because from the parser point of view, spaces, tabs, commas, semicolons, parenthesis and equals are delimiters. All these lines fail the same way (tabs omited)
echo data 1>>somewhere.txt
echo data,1>>somewhere.txt
echo data;1>>somewhere.txt
echo data=1>>somewhere.txt
echo data(1>>somewhere.txt
echo data)1>>somewhere.txt
How to handle it? It is necessary to separate the digit from the redirection, so we can change the order in the line
>somewhere.txt echo data,1
or force the parser see the separation
(echo data,1)>somewhere.txt
or, if the data is inside a variable, we can also use delayed expansion
set "n=1"
setlocal enabledelayedexpansion
echo data,!n!>somewhere.txt
Of course, we can also do
echo data,1 >>somewhere.txt
including a space between the data and the redirection, but the space will be included in the redirected data.
Another option is to reorganize the code
#ECHO OFF
SET objectCounter=1
SET /p "objectName=What is the name of the object %objectCounter%?: "
SET /p "objectNumber=How many of object %objectCounter% are there?: "
SET /p "objectCategory=Which group does object %objectCounter% belong to?: "
> objects.txt (
ECHO OBJECTNAME%objectCounter%,%objectName%
ECHO OBJECTNUMBER%objectCounter%,%objectNumber%
ECHO OBJECTCATEGORY%objectCounter%,%objectCategory%
)
It looks like it has to do with output redirection in conjunction with the comma. I think, with the comma in there, the numeric value is being bound to the redirection rather than to the thing being output.
In other words, while:
set x=1
echo xyzzy%x%>qq.txt
will work (the thing being output is xyzzy%x% with a redirection of >qq.txt), the following will not:
set x=1
echo xyzzy,%x%>qq.txt
(presumably because the thing being output is xyzzy, with a redirection operation 1>qq.txt which is the same as >qq.txt). That also explains the difference you're seeing between 1 and other numbers since 1 is standard output.
You can see a similar problem even without variable expansion:
C:\pax> echo xyzzy1>qq.txt
C:\pax> type qq.txt
xyzzy1
C:\pax> echo xyzzy,1>qq.txt
C:\pax> type qq.txt
xyzzy,
One way around it is to reorganise your components so that the numeric value cannot be tied to the redirection:
>>objects.txt ECHO OBJECTNUMBER%objectCounter%,%objectNumber%
I tend to prefer putting them at the start since using something like:
echo xyzzy >file
will actually output xyzzy and the space immediately before the >.
Modifying the lines like that (and fixing your third echo so it outputs the category rather than the number again) gives you:
What is the name of the object 1?: Apple
How many of object 1 are there?: 1
Which group does object 1 belong to?: Fruit
with the resultant file being:
OBJECTNAME1,Apple
OBJECTNUMBER1,1
OBJECTCATEGORY1,Fruit

If statements in Batch for strings don't return true?

:start
net view
set nick=
echo.
echo.
echo If you want to select a common target, enter one of the following:
echo (computer1)
echo (computer2)
echo (computer3)
set /P target="Enter one of the above computer names (without \\):
IF "%target%"=="(computer1)" do(
set nick=(computer1)
goto shortcut
)
IF "%target%"=="(computer2)" do(
set nick=(computer2)
goto shortcut
)
IF "%target%"=="(computer3)" do(
set nick=(computer3)
goto shortcut
)
ELSE goto shutdown
The above code is a program that is supposed to allow you to type in a shortcut to store a computer name in the variable nick.
I'm very new to batch, FYI.
When I run the program, the first if statement executes no matter what (even when %target% is a different value). How can I reslove this? I've done thorough research with comparing strings and none have worked.
P.S. I need to use nick in the :shutdown page so I really need that value to be set based on what the user inputs. Also, the (computers) aren't part of the program; they're actual computer names that I replaced for the sake of the privacy.
Thanks!
IF "%target%"=="(computer1)" do( should be
IF "%target%"=="(computer1)" (
set nick=(computer2) (and alike) should be
set nick=^(computer2^)
ELSE has wrong synax, should be ) ELSE (
missing labels
Try following code
:start
net view
set nick=
echo.
echo.
echo If you want to select a common target, enter one of the following:
echo (computer1) = home
echo (computer2) = guy
echo (computer3) = andre
set /P target="Enter one of the above computer names (without \\):"
IF "%target%"=="home" set nick=(computer1)
IF "%target%"=="andre" set nick=(computer2)
IF "%target%"=="guy" set nick=(computer3)
IF "%nick%"=="" goto shutdown
goto shortcut
:shortcut
Rem program for shotcut may be placed here
echo "%target%"
goto end
:shutdown
Rem program for shutdown may be placed here
:end
I simplify IF-block of your code.
As JosefZ mentioned, usage of "do" in your code is wrong (syntactic error).
That error cause to ignore 'first if statement' of your code, and make next line "set nick=(computer1)" to be executed. This is the reason why it looks "the first if statement executes no matter what".

Filename manipulation in cygwin

I am running cygwin on Windows 7. I am using a signal processing tool and basically performing alignments. I had about 1200 input files. Each file is of the format given below.
input_file_ format = "AC_XXXXXX.abc"
The first step required building some kind of indexes for all the input files, this was done with the tool's build-index command and now each file had 6 indexes associated with it. Therefore now I have about 1200*6 = 7200 index files. The indexes are of the form given below.
indexes_format = "AC_XXXXXX.abc.1",
"AC_XXXXXX.abc.2",
"AC_XXXXXX.abc.3",
"AC_XXXXXX.abc.4",
"AC_XXXXXX.abc.rev.1",
"AC_XXXXXX.abc.rev.1"
Now, I need to use these indexes to perform the alignment. All the 6 indexes of each file are called together and the final operation is done as follows.
signal-processing-tool ..\path-to-indexes\AC_XXXXXX.abc ..\Query file
Where AC_XXXXXX.abc is the index associated with that particular index file. All 6 index files are called with **AC_XXXXXX.abc*.
My problem is that I need to use only the first 14 characters of the index file names for the final operation.
When I use the code below, the alignment is not executed.
for file in indexes/*; do ./tool $file|cut -b1-14 Project/query_file; done
I'd appreciate help with this!
First of all, keep in mind that $file will always start with "indexes/", so trimming first 14 characters would always include that folder name in the beginning.
To use first 14 characters in a variable, use ${file:0:14}, where 0 is the starting string index, and 14 is the length of the desired substring.
Alternatively, if you want to use cut, you need to run it in a subshell: for file in indexes/*; do ./tool $(echo $file|cut -c 1-14) Project/query_file; done I changed the arg for cut to -c for characters instead of bytes

Resources