How to convert JSON syntax to another one with a cmd.exe batch file (for loop) - batch-file

I have 10000 tiny tmp/ txt files that look like these:
1.tmp: {"a": "you","data": "1","data2": "2"} <linefeed> {"b":"bo"}
2.tmp: {"a": "you2","data": "1","data2": "2"} <linefeed> {"b":"bo2"}
3.tmp: {"a": "you3","data": "1","data2": "2"} <linefeed> {"b":"bo3"}
How can I read each of them and convert these to another format, one file that has 1 row per file:
{ "a": "you", "b": "bo" },
{ "a": "you2", "b": "bo2" },
{ "a": "you3", "b": "bo3" },
The tricky part might be that each .tmp file has a linefeed?
My code starts
for /L %%i in (0,1,10000) do (call parsesomehow %%i.tmp )

As I understood there were only 2 lines in every tmp file.
You have to read every tmp file. In every cycle you should parse 1-st string. Then - 2-nd. This parce cycle must be the stored procedure
Next step is print parsed values to output file.
#echo off
for %%i in (*.tmp) do call :parse %%i
goto :EOF
:parse
for /f "delims=," %%a in (%1) do set "A=%%a" &goto NXT
:NXT
for /f "delims={" %%a in ('more +1 %1') do set "B=%%a"
echo %A%, %B%>>output.txt

Related

How to substitute a string in batch script?

My arqtext.txt has the following dataset:
A,B,C,
(123 or 456) and (789 or 012),1,5,
(456 or 654) and (423 or 947),3,6,
(283 or 335) and (288 or 552),2,56,
I want to change the 1st column of the last 3 rows to a new string set in the script, with the result like:
A,B,C,
roi1,1,5,
roi2,3,6,
roi3,2,56,
But my code only output the header "A,B,C,":
#echo off
setlocal EnableDelayedExpansion EnableExtensions
set roi1="(123 or 456) and (789 or 012)"
set roi2="(456 or 654) and (423 or 947)"
set roi3="(283 or 335) and (288 or 552)"
set /p "header="<"arqtext.txt"
echo %header%>arqtextnovo.txt
for /f "skip=1 tokens=1,* delims=," %%a in ("arqtext.txt") do (
if %%a=="roi1" (
echo roi1,%%b>>arqtextnovo.txt
)
if %%a=="roi2" (
echo roi2,%%b>>arqtextnovo.txt
)
if %%a=="roi3" (
echo roi3,%%b>>arqtextnovo.txt
)
)
rem EXIT /B
pause>nul
This is the way I would do it:
#echo off
setlocal EnableDelayedExpansion
set "roi[(123 or 456) and (789 or 012)]=1"
set "roi[(456 or 654) and (423 or 947)]=2"
set "roi[(283 or 335) and (288 or 552)]=3"
set /P "header=" < "arqtext.txt"
> arqtextnovo.txt (
echo %header%
for /f "usebackq skip=1 tokens=1,* delims=," %%a in ("arqtext.txt") do (
echo roi!roi[%%a]!,%%b
)
)
rem EXIT /B
pause>nul
The for /F command requires "usebackq" option if the filename is enclosed in quotes. Otherwise, it process the literal string enclosed in quotes.
It is more efficient to (redirect the whole output) > to a file, instead of append >> every new line. This also avoid the problems of redirect lines that ends in numbers.
If you have several values and want to select a result value based on the first one, it is much simpler and more efficient to use an array instead of test each individual value.
Let's suppose this method:
set /P "selector=Enter selector: "
if "%selector%" equ "nine" set result=9
if "%selector%" equ "seven" set result=7
if "%selector%" equ "five" set result=5
Instead, you may define an array called "value":
set "value[nine]=9"
set "value[seven]=7"
set "value[five]=5"
... and then directly get the result value this way:
set "result=!value[%selector%]!"
The same method is used in this code. However, you have not specified what happen if the input value is not one of the array elements.
For a further description on array management in Batch files, see this answer

Get values of httpresponse using batch file

For example I have this HTTP Response:
{
"location": {
"lat": 51.0,
"lng": -0.1
},
"accuracy": 1200.4
}
How do I get only the values 51.0 and -0.1? I tried doing it with this:
for /F "tokens=3 delims= " %%a in (foo1.tmp) do (
echo %%a >> url.tmp
)
set /p lat=<url.tmp
more +1 <url.tmp >new.tmp
for /F "tokens=* delims= " %%a in (new.tmp) do (
set var2=%%a
)
I was able to get the first value which was 51.0 but for the second value which as var2, I am getting the 1200.4 value which is supposed to be -0.1. Any help here?
To better explain what my one liner from the comment does:
findstr "lat lng" <foo1.tmp
filters lines containing either lat or lng using default regular expression mode, sample output:
"lat": 51.0,
"lng": -0.1
Instead of using a temporary file, you can directly use curl/wget
To process the output the for /f parses the line with the delimiters :, (colon,comma,space).
Leading delims are ignored, adjacent ones are counted as only one, so
%%A contains "lat" / "lng"
%%B contains 51.0 / "-0.1"
To strip the double quotes from %%A the for variable modifier ~ is used.
In summary the (batch) line:
for /f "tokens=1,2 delims=:, " %%A in ('findstr "lat lng" ^<foo1.tmp') do set "%%~A=%%B"
sets the variables
> set l
lat=51.0
lng=-0.1

How to check which folders from the array exist?

I need to execute some command in each of the folder from the given list if it (folder) exists.
What wrong with this script?
#echo off
set FILE_LIST=(a b c d file)
for %%i in %FILE_LIST% do (
IF EXIST %cd%\%%~i (
set flag=Yes
) else (
set flag=No
)
:: Just for problem illustration, for SO
echo "%%i": %flag%
if %flag%=="Yes" (
start somecommand %cd%\%%~i\program.exe
)
)
Result of execution:
C:\Temp>script.bat
"a": No
"b": No
"c": No
"d": No
"file": No
Folder content:
You might be overcomplicating this a bit, why not just do:
#echo off
for %%i in (a b c d file) do if exist "%%i" echo "%%i"
so if you wanted to run a program, then just do:
#echo off
for %%i in (a b c d file) do if exist "%%i" start "somecmd" "%%i\program.exe"

Print single lines, and a number of lines, with the contents i text file. Batch skript

I would like to print single lines,or a number of lines, with the contents, between the desired line numbers (from the n to m lines numbers), in text file!
I have trouble printing lines, with the contents, under number lines 10, both single lines (eg, only 1, or 4, etc.), or several desired lines (eg from 1 to 9 or from 3 to 13 etc.) in the text file. To print liner, with contents, over number lines 10, both single lines (eg, only 11, or 16, etc.) and the desired number of lines (eg 10 to 19 or 14 to 16, etc.) works well. Where I'm wrong?
CODE:
#echo off
for /f "tokens=1* delims=:" %%a in ('findstr /n .* "data.txt"') do (
if "%%a" EQU "%1" echo.%%b else (if "%%a" GTR "%1" if "%%a" LSS "%2" echo.%%b))
::>>temp.txt
if "%%a" EQU "%1" echo.%%b else (if "%%a" GTR "%1" if "%%a" LSS "%2" echo.%%b))
should be
if "%%a" EQU "%1" (echo.%%b) else (if "%%a" GTR "%1" if "%%a" LSS "%2" echo.%%b))
as batch needs to differentiate between echo %%b and echo %%b else ... being alternative strings to echo.
Perhaps you should also see This earlier example which makes me feel that this is homework...

SUBSTRING a filename in batch

I need help to make a batch code (if it's possible) to get substring from filename.
My filename can be like (filename lenght is changing):
7_D_D1_012345678-2015-07-07.pdf
8_A_087654321-2015-07-07.pdf
10_D_D1_011122558-2015-07-07.pdf
100_C_CCC1_C2_C3_C4_055555555-2015-07-07.pdf
file number - from left to first _
id1 - from 1 to n string with _ separator; for example C_C1_C2_C3_C4
id2 - always 9 digits; for example 011122558
date - for example 2015-07-07
extension .jpg
How to loop substring (file number, id1, d2, date) for all filenames in folder and put it to my code
convert - "file number" -annotate "id1" -annotate2 "id2" -annotate "date"
for example:
convert - "01" -annotate "C_C1" -annotate2 "012345678" -annotate "2015-07-07"
Thanks for help.
pure batch. Simple string manipulation mixed with tokenization. No need for additional utilities.
(g.txt holds your example file names; could be replaced by 'dir /b /a-d')
#echo off
for /f %%i in (g.txt) do call :process %%i
goto :eof
:process
set x=%1
set ext=%x:*.=%
for /f "delims=_" %%i in ("%x%") do set fileno=%%i
for /f "tokens=1,*delims=-" %%i in ("%x%") do (
set x1=%%i
set x2=%%j
)
for /f "tokens=1,* delims=." %%i in ("%x2%") do (
set dat=%%i
set ext=%%j
)
set id2=%x1:~-9%
for /f "tokens=1,* delims=_" %%i in ("%x1:~0,-10%") do set id1=%%j
echo filename %x%
echo ------------------------
echo Nr. %fileno%
echo ID1 %id1%
echo ID2 %id2%
echo Date %dat%
echo Ext. %ext%
echo ------------------------
echo convert - "%fileno%" -annotate "%id1%" -annotate2 "%id2% -annotate "%dat%"
echo(
echo(
goto :eof
Since you said Windows 7, I know you have Powershell available. Here is a Powershell script:
$re = '^(\d+)_((?:(?:[a-zA-Z0-9]+)_?)+)_(\d{9})-(\d{4}-\d\d-\d\d)\.(\w+)$'
dir | ForEach-Object {$_ -replace $re, 'convert "$1" -annotate "$2" -annotate2 "$3" -annotate3 "-$4"'}
Given the filenames you gave in your question
7_D_D1_012345678-2015-07-07.pdf
8_A_087654321-2015-07-07.pdf
10_D_D1_011122558-2015-07-07.pdf
100_C_CCC1_C2_C3_C4_055555555-2015-07-07.pdf
It will produce this text output:
convert "100" -annotate "C_CCC1_C2_C3_C4" -annotate2 "055555555" -annotate4 "2015-07-07"
convert "10" -annotate "D_D1" -annotate2 "011122558" -annotate4 "2015-07-07"
convert "7" -annotate "D_D1" -annotate2 "012345678" -annotate4 "2015-07-07"
convert "8" -annotate "A" -annotate2 "087654321" -annotate4 "2015-07-07"
(The filenames were sorted first, so the one starting with 100 comes first and the one starting with 8 comes last).
By redirecting this text output into a .cmd file, you can execute the convert commands as desired.
Here is the breakdown of that regular expression:
Beginning of line or string
[1]: A numbered capture group. [\d+]
Any digit, one or more repetitions
_
[2]: A numbered capture group. [(?:(?:[a-zA-Z0-9]+)_?)+]
Match expression but don't capture it. [(?:[a-zA-Z0-9]+)_?], one or more repetitions
(?:[a-zA-Z0-9]+)_?
Match expression but don't capture it. [[a-zA-Z0-9]+]
Any character in this class: [a-zA-Z0-9], one or more repetitions
_, zero or one repetitions
_
[3]: A numbered capture group. [\d{9}]
Any digit, exactly 9 repetitions
-
[4]: A numbered capture group. [\d{4}-\d\d-\d\d]
\d{4}-\d\d-\d\d
Any digit, exactly 4 repetitions
#echo off
setlocal enableextensions disabledelayedexpansion
rem For each file
for /r "x:\starting\folder" %%z in (*.pdf) do (
rem Separate number part
for /f "tokens=1,* delims=_" %%a in ("%%~nz") do (
set "_number=%%~a"
set "_file=%%~fz"
rem Separate date and ids
for /f "tokens=1,* delims=-" %%c in ("%%~b") do (
set "_date=%%~d"
set "_ids=%%~c\."
)
)
rem Separate id1 from id2 handling the string as a path
rem This way id2 is the last element and the path to it
rem is id1
setlocal enabledelayedexpansion
for /f "delims=" %%e in ("::!_ids:_=\!") do (
endlocal
set "_id2=%%~nxe"
set "_id1=%%~pe"
)
rem Correct id1 contents (it is a path) changing backslashes
rem to underscores. As there are initial and ending backslashes,
rem later we will remove the initial and ending underscores
setlocal enabledelayedexpansion
for /f "delims=" %%e in ("!_id1:\=_!") do (
endlocal
set "_id1=%%~e"
)
rem Execute final command
setlocal enabledelayedexpansion
echo(
echo file[!_file!]
echo convert - "!_number!" -annotate "!_id1:~1,-1!" -annotate2 "!_id2!" -annotate "!_date!"
endlocal
)

Resources