How to remove special characters from string using batch - string

I have very little knowledge in batch programming. I want to remove special characters from string Suppose If String= " How:to,convert special characters" wants to convert into this " How-to-convert-special-characters " ( how to do if there are multiple characters like ,; : ) Kindly help! Thanks

#ECHO OFF
SETLOCAL
SET String=" How:to,convert special characters how to do if there are multiple characters like ,; : "
SET string1=%string:,=comma%
SET string2=%string:;=semicolon%
SET string3=%string::=fullcolon%
SET string4=%string3:;=SEMICOLON%
SET string4=%string4:,=COMMA%
SET string
The simple formula is SET varname2=%varname1:stringtoreplace=replacement%
It does have limits though. You would run into problems with certain characters like ^="% amongst others.

You may use the substring replacement to change individual characters, as Peter Wright suggested, but this method preserve multiple characters, so a further change of multiple dashes by just one would be needed. If your objective is to separate words with just one dash eliminating multiple separation characters (even multiple spaces), then you may use a different method.
The FOR Batch command process words separated by spaces (single or multiple):
for %%a in (one two three four ) do echo %%a
one
two
three
four
You may use Delayed Expansion to collect the words processed by FOR command into a single variable (for details, type set /? and look for "delayed expansion"):
setlocal EnableDelayedExpansion
set string=
for %%a in ( one two three four ) do set string=!string! %%a
echo "%string%"
" one two three four"
The standard separators for FOR words may be commas, semicolons and equal-signs, besides spaces (single or multiple):
for %%a in (one,two= ;; ,, three ===;;;,,, four ) do ...
This way, you may directly use a FOR command to eliminate multiple spaces, commas, semicolons (and equal-signs):
for %%a in (%string%) do ...
If you want to also eliminate one character more (like colon), you may change that character by space (or comma, semicolon or equal-sign) in the same FOR command:
for %%a in (%string::=;%) do
If you want to eliminate more characters, you may first change all of them in the string and then use FOR.
The Batch file below read a string and change multiple spaces, commas, semicolons, (equal-signs); colons and points, and insert a single dash between words:
#echo off
setlocal EnableDelayedExpansion
set /P input=Enter a string:
set input=%input:.=,%
set output=
for %%a in (%input::=;%) do set output=!output!%%a-
rem Eliminate the last dash:
set output=%output:~0,-1%
echo Output: "%output%"
You must note that not all special characters can be processed this way.

Related

How to get a substring with special characters in batch file?

I'm trying to remove a part of a string with special characters.
The string looks like: <abc>123</abc>
I want to extract only 123
I've tried
set substr=<abc>
%my_string:substr=%
and removing character by position
set result=%my_string:~5,-6%
but neither works. Someone can help me?
ps. I'm new in batch.
sorry for the english.
Delayed expansion and double quoting of strings are the methods needed here.
The use of the for loop is just as a way of defining all substrings to be removed in the one line.
#echo off
Setlocal enabledelayedexpansion
set "string=<abc>123</abc>"
For %%A in ("<abc>" "</abc>") do Set "string=!string:%%~A=!"
Echo(!string!
pause

Remove string upto the first occurrence of a character using batch script

I have a variable say
var="dev02,qa02,stage,prod,dev02_loc,qa02_loc,stage_loc,prod_loc"
I need to convert this into
qa02,stage,prod,dev02_loc,qa02_loc,stage_loc,prod_loc
by removing all the characters before the first occurence of ,
How can I do this using batch script?
What you can do is to use variable expansion and substitution.
In this case given your stated variable content of:
dev02,qa02,stage,prod,dev02_loc,qa02_loc,stage_loc,prod_loc
You could simply expand the variable, substituting everything up to the first comma with nothing:
Echo(%var:*,=%
For setting your initial variable, %var%, you should change the syntax to this:
Set "var=dev02,qa02,stage,prod,dev02_loc,qa02_loc,stage_loc,prod_loc"
This will prevent the doublequotes from being included in the variable value, prevent accidental trailing whitespace and protect the content.
You can use a for loop (see for /?) delimit on , and do something with the result:
#set "var=dev02,qa02,stage,prod,dev02_loc,qa02_loc,stage_loc,prod_loc"
#for /f "tokens=1* delims=," %%i in ("%var%") do #echo(%%j

Remove empty lines from a preformatted CSV

im generating a CSV from an XLS file with VBA, after that I am filtering the CSV with Batch. My filter looks like this:
for %%a in (*.csv) do (
for /f "usebackq tokens=1-10 delims=, eol=^" %%1 in ("%%a") do (
if %%4 EQU Req_Category ECHO %%1,%%2,%%3,%%4,%%5,%%6,%%7,%%8,%%9 >> "%%a"_JIRA.csv
if %%4 EQU Requirement ECHO %%1,%%2,%%3,%%4,%%5,%%6,%%7,%%8,%%9 >> "%%a"_JIRA.csv
)
)
This works fine if the CSV File has no empty lines.
In rare occasions the XLS -> CSV converting generates empty lines or CRs in the CSV.
SW_Fn-289,4.1.1.1,Controling Hardware PCB,Heading,,,,,IgnoreTesting,
SW_Fn-291,4.1.1.1.0-1,"
Date : 07.03.1777
The SystemDesignSpecification is stored in SVN path
http://sblablablabla.xlsm
",Requirement,Lab1 (B-Sample),,Released,Accepted,IgnoreTesting,
SW_Fn-4281,4.1.1.1.0-2,"
Date : 123.123.123
Path : https://apath.com
",Requirement,R1,,New,New,IgnoreTesting,
SW_Fn-166,4.2,Compliance Requirements,Heading,,,,,IgnoreTesting,
SW_Fn-286,4.2.1,Resource Usage,Heading,,,,,IgnoreTesting,
Every line in the CSV should start with an ID: SW_Fn-Example.
Does every one have an idea how can bring the info on one line with a batch function?
I need to get the file to look like this (before filtering):
SW_Fn-289,4.1.1.1,Controling Hardware PCB,Heading,,,,,IgnoreTesting,
SW_Fn-291,4.1.1.1.0-1,"Date : 07.03.1777 TheSystemDesignSpecificationisstored in SVN path http://sblablablabla.xlsm",Requirement,Lab1 (B-Sample),,Released,Accepted,IgnoreTesting,
SW_Fn-4281,4.1.1.1.0-2," Date : 123.123.123 Path : https://apath.com",Requirement,R1,,New,New,IgnoreTesting,
SW_Fn-166,4.2,Compliance Requirements,Heading,,,,,IgnoreTesting,
SW_Fn-286,4.2.1,Resource Usage,Heading,,,,,IgnoreTesting,
There shouldnt be a line that does not start with SW_Fn-blabla. If a line starts with something else, then it should be a part of the previous line that has an Sw_Fn-blabla.
Then my filter will work to produce this:
SW_Fn-291,4.1.1.1.0-1,"Date : 07.03.1777 TheSystemDesignSpecificationisstored in SVN path http://sblablablabla.xlsm",Requirement,Lab1 (B-Sample),,Released,Accepted,IgnoreTesting,
SW_Fn-4281,4.1.1.1.0-2," Date : 123.123.123 Path : https://apath.com",Requirement,R1,,New,New,IgnoreTesting,
Thanks in advance
try this:
#echo off
for %%a in (*.csv) do (
for /f "delims=" %%b in (%%a) do (
for /f "tokens=4 delims=," %%c in ("%%b") do (
if "%%c"=="Requirement" echo %%b >>%%~na_JIRA%%~xa
if "%%c"=="Req_Category" echo %%b >>%%~na_JIRA%%~xa
)
)
)
read and handle each line complete to overcome the consecutive-delimiter-issue mentioned by Magoo (use another for to check Token4, but don't bother to disassemble and reassemble the complete line)
Aak! don't use numerics for the metavariable (%%1) - it's highly unreliable. Use an alphabetic character.
Batch treats a string of delimiters as a single delimiter and you have nominated commas and spaces as delimiters, so
SW_Fn-166,4.2,Compliance Requirements,Heading,,,,,IgnoreTesting,
would appear as
SW_Fn-166,4.2,Compliance,Requirements,Heading,IgnoreTesting,,,,
You haven't shown what you expect as output. Do you only want the lines that begin SW_Fn- or do you want all lines that don't start SW-Fn appended to the last line that did?
#ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q36475816.csv"
SET "outfile=%destdir%\outfile.txt"
SET "line="
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
SET "newpart=%%a"
IF DEFINED line CALL :test
IF DEFINED line CALL SET "line=%%line%% %%a"
IF NOT DEFINED line SET "line=%%a"
)
IF DEFINED line ECHO(%line%
)>"%outfile%"
GOTO :EOF
:: Test new data " Accumulate data into line or output & start a new line
:test
SET "newpart=%newpart:"=x%"
IF NOT "%newpart:~0,6%"=="SW_Fn-" goto :eof
echo(%line%
SET "line="
GOTO :eof
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used a file named q36475816.csv containing your data for my testing.
Produces the file defined as %outfile%
Note that your posted data contains unbalanced quotes in the Fn-4281 item. It's always better to use actual data rather than "somewhere close".
Read each line. If we've already accumulated part of a line, check whether the first few characters are the target. If they are, output the line as constructed and clear line.
If line is clear after this operation, set it to the line read (which must startwith the target, otherwise accumulate the line.
In the :test procedure, remove quotes before testing so that it doesn't break the syntax. Obviously, if the first few characters contains a quote, it doesn't fit the target so the test will correctly detect "no fit"
Your file is actually valid CSV format. Quoted CSV fields may contain any of the following:
comma
quote literal, escaped as ""
newline (either LF or CRLF)
You don't have commas or quotes within your fields, but you do have newlines that are giving your code serious problems.
But that is only one potential problem. Another issue is FOR /F treats consecutive delimiters as a single delimiter, so if any of your desired keeper lines have any empty fields, then your output will be completely wrong.
Batch is inherently far from ideal for any kind of text processing, but for CSV it is especially bad for all but the most simplest problems. If you really want to use batch, you could use ParseCSV.bat to properly parse your CSV and read it using FOR /F in a reliable manner. But there are better options.
PowerShell has an Import-Csv cmdlet. I'm not sure of its capabilities, but if it supports newlines within fields, then you could develop a really slick solution with that.
Another option is my JREPL.BAT regular expression text processor. The following code looks nasty, but it will very efficiently produce your desired output in one step:
jrepl "((?:[\s\S]*?,){3}(?:(Req_Category,|Requirement,)|.*?,)(?:.*?,){4}.*?),[^,\n]*\n?" "$2?$1.replace(/\r\n/g,' ')+'\r\n':''" /m /j /f input.csv /o output.csv
You would need to use CALL JREPL if you put the command within another batch script.
My JREPL solution relies on the fact that none of your input fields contain quoted commas. If it did contain quoted commas, then a JREPL solution would be even more complicated.
This solution works by using the /M multiline option so that I can match across line-breaks.
The search matches each 10 field collection (your 10th field seems to be always empty), regardless of line breaks. $1 contains the first 9 fields (without the trailing comma). $2 contains the 4th field if and only if it matches "Req_Category" or "Requirement". The replacement javascript expression tests if $2 is defined, and if it is, then the whole search expression is replaced with $1 after all newlines have been replaced by spaces, and then a newline is appended. IF $2 is not defined then the whole search expression is replaced with an empty string. Simple in concept, but kind of nasty to develop ;-)
A slight simplification allows you to preserve the original fields containing newlines, and still do the filtering you desire.:
jrepl "((?:[\s\S]*?,){3}(?:(Req_Category,|Requirement,)|.*?,)(?:.*?,){4}.*?),[^,\n]*\n?" "$2?$1+'\r\n':''" /m /j /f input.csv /o output.csv

Split string by special characters '*' in batch file

I need to delete the substring after *. with a batch file
Example :
The value of string is : TEST_SINISTRE*.csv
rem My code :
SET mystring="TEST_SINISTRE*.csv"
rem Do the split
SET ext_test=%mystring:*.="& rem %"
SET ext_test=%ext_test%
rem what i get
echo %ext_test% ===> "& rem csv"
rem What i want to see
===> TEST_SINISTRE
Can you help me :-)
If, and only if, the *. pattern can only occur once in the string, and the part after *. is not contained in the part before *., the following could be used:
rem this is the original string containing one `*.`:
set "STRING=TEST_SINISTRE*.csv"
rem now get everything after `*.`:
rem (if `*` is the first character in substring substitution, it means everything up to
rem and including the search string is to be replaced, by nothing here in this case)
set "SUBSTR=%STRING:**.=%"
rem get everything before `*.`, including the `*`:
setlocal EnableDelayedExpansion
set "SUBSTL=!STRING:.%SUBSTR%=!"
rem truncate the `*` from the string:
endlocal & set "SUBSTL=%SUBSTL:~,-1%"
Since the substitution syntax for variable expansion is used, this is done in a case-insensitive manner.
To make it more secure, you could append something that will most probably never occur to your original string temporarily and remove it afterwards. To accomplish this, replace the set command line between the setlocal/endlocal block with the following (using appendix ### here for instance):
set "STRING=!STRING!###"
set "SUBSTL=!STRING:.%SUBSTR%###=!"
The * character is a wildcard in batch variable substring substitution. When you do *.=something in an inline substitution, you're really saying "replace everything up to and including the dot". You should use a for /F loop so you can specify the asterisk as a delimiter.
set "str=TEST_SINISTRE*.csv"
for /f "tokens=1* delims=*" %%I in ("%str%") do set "ext_test=%%I%%J"
echo %ext_test%
I'm not sure what your ultimate goal is, but here's a hacksy possible alternative. You could actually create a file called TEST_SINISTRE.csv and then capture the filename into a variable as a wildcard match.
set "str=TEST_SINISTRE*.csv"
type NUL > TEST_SINSTRE.CSV
for %%I in (%str%) do set "ext_test=%%I"
echo %ext_test%
I'm sure that's not exactly you have in mind, but it does demonstrate that maybe you don't need to strip the asterisk if you are going to be performing filename matching.

Extract a file name out of a path found in an ini file

I need to extract information from a path found on a line in a batch file. Specifically the line says:
GLOBP4P=C:\folderx\foldery\folderz\datag.p4p
What I need to extract is the part above identified as "data". The g.p4p is always present, the GLOBP4P is always present, but the things in between can be varying from file to file. I essentially want to strip the g.p4p and then write whatever is left to the first "\" to a variable. in this case the variable would store "data". The problem I have is that "data" can be any number of characters, also there can be any number of path folders, etc.
I attempted to do aFor /f with "\" as a delim to try and break the string apart, but since i don't know how many folders there will be I don't know how to identify taking the last one (i.e. the filename) exclusively.
Thanks
This should work too:
#echo off
for /f "delims=" %%a in ('findstr /i "GLOBP4P=" "file.ini"') do set "var=%%~na"
set "var=%var:~0,-1%"
echo "%var%"
Try this. You will get the LAST occurence finded in your ini file :
#echo off
::The name of the bat file to test
Set $bat="The_ini_file_to_test.ini"
::Finding the string "GLOBP4P" and setting the value in it
for /f %%a in ('findstr /i "GLOBP4P" "%$bat%"') do set %%a
::Getting the first and the Last element of the path
set first=%GLOBP4P:\=&set last=%
::Outputting some results
echo File : [%last%]
echo Data : [%last:~0,-5%]
echo drive : [%first%]
#echo off
set GLOBP4P=C:\folderx\foldery\folderz\datag.p4p
for %%a in ("%GLOBP4P%") do set var=%%~Na
set var=%var:~0,-1%
echo %var%
EDIT: Some explanations added
In a FOR command, %%~N return just the file name of the FOR parameter, in this case is datag string. Enter FOR /? for further details.
When a variable is expanded via %var%, the %var:~START,LEN% notation indicate to extract a substring starting at START character (beginning at zero) and with LEN characters. If LEN have minus sign, indicate the last character backwards from string end. In this case, %var:~0,-1% indicate to extract all but last characters from var, that is, eliminate the last character from datag string. Enter SET /? for further details.

Resources