Batch - Extract every word on a line to a markdown link - batch-file

This is code from a call above it. I extract line 5 from a file with this code which leaves it in %%c. I then want to take each word in that line (there can be from 1 to nth words) and create a markdown link like
[word](word.html)
and append those to a txt file. This is what I have so far. If I have 10 words do I really have to add all the tokens in the command like %%d, %%e, etc.? Can I use something like tokens=1-*. * meaning the last token in the line? Using tokens=* uses the whole line of words as one token I believe.
setlocal enabledelayedexpansion
set "lineNr=5"
set /a lineNr-=1
for /f "usebackq delims=" %%c in (`more +!lineNr! "%~1"`) DO (
for /f "tokens=1-2 delims= " %%d in ("%%c") do (
echo [%%d]^(tags/%%d.html^) [%%e]^(tags/%%e.html^) ^<br^> >> index.txt
)
goto :eof
)

Here is an example of how you can do that. Note I just used some parts as an example as I do not have time to format escape characters now, but you'll get the idea :)
#echo off
set "lineNr=5"
set /a lineNr-=1
for /f "usebackq delims=" %%c in (`more +%lineNr% "%~1"`) DO set "line=%%c"
for %%i in (%line%) do echo| set /p =[%%i](tags/%%i.html)>>index.txt

OK, I got it working by doing this -
set "lineNr=5"
set /a lineNr-=1
for /f "usebackq delims=" %%c in (`more +%lineNr% "overview.md"`) DO (
set "line=%%c"
goto :next
)
:next
for %%i in (%line%) do echo| set /p =[%%i](tags/%%i.html) >> index.txt
Have to break out of the loop line listing after the first line wanted(line 5).

Related

How to extract a word after specific character in batch program?

For example I have a text file test.txt that contains like this:
Item1 $23 Item2 $24
Item3 $25
When I run this script:
#echo off
for /f "delims=$ tokens=1*" %%A in (test.txt) do echo %%B >> result.txt
The result is:
23 Item2 $24
25
I want the result is:
23
24
25
How should I repair the script?
Try the following script (see the explanatory rem remarks in the code):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_IFILE=test.txt"
set "_OFILE=result.txt"
rem // Store line-break in variable:
(set ^"LF=^
%= blank line =%
^")
rem // Write to resulting file:
> "%_OFILE%" (
rem // Loop through lines of text file:
for /F "usebackq delims=" %%L in ("%_IFILE%") do (
rem // Store current line in variable:
set "LINE=%%L"
rem // Toggle delayed expansion to be able to write and read variable in same code block:
setlocal EnableDelayedExpansion
rem // Replace each `$` by line-break and loop over resulting lines skipping the first one:
for /F "skip=1" %%K in (^"!LINE:$^=^%LF%%LF%!^") do (
rem // Return first token of each line:
echo(%%K
)
endlocal
)
)
endlocal
exit /B
At first, this replaces every $ by a line-break, so the first line of test.txt becomes:
Item1
23 Item2
24
And the second one becomes:
Item3
25
Then it extracts the first SPACE- or TAB-separated token from each of the newly formed multi-line strings, skipping the first line, so only the numbers are returned.
I have decided to post this example batch-file to show a method of parsing each line and returning every other string, (doesn't work with poison characters).
#(For /F "UseBackQDelims=" %%A In ("test.txt")Do #(Set "i=0"
For %%B In (%%A)Do #(Set /A "i=(i+1)%%2"&Cmd /V:On /Q /C Exit !i!
If Not ErrorLevel 1 Echo %%B)))>"results.txt"
In your posted example code and 'wanted' result, you could probably use that idea to output the strings with their first character removed if it is a $.
#(For /F "UseBackQDelims=" %%A In ("test.txt")Do #(Set "i=0"
For %%B In (%%A)Do #(Set /A "i=(i+1)%%2"&SetLocal EnableDelayedExpansion
If !i! Equ 0 (Set "Val=%%B"&If "!Val:~,1!"=="$" (Echo !Val:~1!
)Else Echo %%B)&EndLocal)))>"results.txt"
This should do exactly what you want.
#echo off
setlocal enabledelayedexpansion
(for /f "usebackq tokens=* delims= " %%i in ("test.txt") do (
set "_br=%%i"
echo(!_br: =^
!
)
)>_tmp
(for /f "delims=$ tokens=*" %%a in ('type _tmp ^| find "$"') do echo %%a)>result.txt
Note that you must copy the script as is. The extract of the script as show below does the replacement of whitespace with new line and therefore cannot change at all, the position and the extra line must remain as is for this to work as intended.
echo(!_br: =^
!
This script just splits each word separated by a space and redirects it to a new file, we then specifically search for the words containing $ and redirect those hits only.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f "delims=" %%A in (test.txt) do (
for %%T in (%%A) do (
set "term=%%T"
if "!term:~0,1!"=="$" echo !term:~1!
)
)>> result.txt
endlocal
Read each line to %%A. Tokenise to %%T. Assign each token in turn to term, examine the first character and if $, echo the term, except the first character.

How to fetch second row, second column from a .csv file?

I have a CSV file that has looks something like below:
Order ID,Order Date,Ship Date,Ship Mode
CA-2011-103800,2013-01-03,2013-01-07 00:00:00,Standard Class
CA-2011-112326,2013-01-04,2013-01-08 00:00:00,Standard Class
All I need is to get from first data row the order date, i.e. 2013-01-03 in this case.
I tried the code below which doesn't solve the problem.
set file=output.csv
for /f "skip=1 tokens=2 delims=," %%A in (%file%) do (echo %%A)
I am a beginner. Can anyone help me out with this?
This can be done VERY easy by creating an array out of the data from file.csv. By using !Line[2]! we can grab any line of the .csv file we want. Simply change the Row & Column configurations to however you need. This can be very useful for searching a .csv file.
#echo off
#setlocal enabledelayedexpansion
Rem | Row & Column Information
Set "Row=2"
Set "Column=2"
Rem | Turn Lines To Array Strings
for /f "tokens=* delims=" %%A in ('Type file.csv') do (
set /a "count+=1"
set "Line[!count!]=%%A"
)
Rem | Grab Second Column From Second Row
for /f "tokens=%Column% delims=," %%A in ('Echo !Line[%Row%]!') do (
set "Data=%%A"
)
Echo Second Row, Second Column Data: %Data%
I left a new Rem notes to help you along in the script process.
Just for fun, here's another alternative. You can redirect your csv file into a loop containing two set /P statements -- one to consume the first line, and the second to set a variable to the second line. Then for the line that was captured, use variable substring substitution to strip away *, and ,*.
#echo off & setlocal
(
set /P "="
set /P "val="
) < "output.csv"
set "val=%val:*,=%"
echo %val:,=&rem;%
But really, your attempted solution is almost correct. All that's needed is to break out of the loop after its first iteration.
#echo off & setlocal
set "file=output.csv"
for /f "usebackq skip=1 tokens=2 delims=," %%A in ("%file%") do echo %%A && exit /b
Something like this using more command to skip the first line and simply get the second token each time:
to get only the first value:
#echo off
set "file=output.csv"
for /f "tokens=2 delims=," %%i in ('type order.txt ^| more +1') do echo %%i & goto next
:next
pause
or to get each second column's value:
#echo off
set "file=output.csv"
for /f "tokens=2 delims=," %%i in ('type %file% ^| more +1') do echo %%i
pause

Locating keyword in .csv files

I am trying to create batch file that reads specific CSV documents from specific file, and extracts some lines that have specific number and print it out on the screen " the whole line !". The problem is I created the code but it wont work at all, whenever I tried it only prints the line numbers!?
The code:
#echo off
setlocal EnableDelayedExpansion
set "yourDir=C:\Users\Adminm\Desktop\test11\"
set "yourExt=csv"
set "keyword=44"
set /a count=0
set linenum=!count!
set c=0
pushd %yourDir%
for %%a in (*.%yourExt%) do (
for /f "usebackq tokens=3 delims=," %%b in (%yourDir%%%a) do (
set /a count = !count! + 1
if NOT %%b == %keyword% (
for /f "delims=" %%1 in ('type %yourDir%%%a') do (
set /a c+=1 && if "!c!" equ "%linenum%" echo %%1%
)
)
)
)
echo !count!
popd
endlocal
thanks in advance <3
for %%a in (*.%yourExt%) do (
for /f "usebackq delims=" %%L in ("%%a") do (
for /f "tokens=3 delims=," %%b in ("%%L") do (
if %%b == %keyword% echo %%L
)
)
)
Assuming what you want to do is scan each file for a target string in column3, then:
Since you have already changed to yourdir, there's no requirement to specify it in the scan-for-filenames for.
Your attempt to locate the required line is clumsy. All you need to do is assign each line in turn to a metavariable (%%L) and then use for/ to parse the metavariable. When the required data matches, simply echo the metavariable containing the entire line.
You've attempted to use %%1 as a metavariable. %n for n=0..9 refers to the parameter number supplied to the routine. The only officially defined metavariables for use here are %%a..%%z and %%A..%%Z (one of the very few places where batch is case-sensitive) - although some other symbols also work. Numerics will not work here.

Through a for /f loop added spaces in the saved variable do not show up in the prompt

I have the possibility to Highlight every letter of a Word with the space key.
The delimeter is a for /f Loop Option. The Output of the variablenmae Word, do not show empty spaces. For example the varaiblenames Word, content is THEWORDISPAT is shown with the used code. Until I try to Output A THEWORDISPAT. In such a case the Output is fused ATHEWORDISPAT. I can not Point to search for what I Need. A non english native user.
#echo off
setlocal enabledelayedexpansion
set logic=13
for /l %%a in (1,1,%logic%) do (call :grapefruit %%a)
goto :eof
goto :main
:grapefruit
set count=0
for %%z in (%1) do (
set /a count+=10%3
set var[!count!]=%%z)
:main
set token= THEWORDIZPAT
for /f "tokens=* delims=" %%b in ("%token%") do (set word=%%b)
set alien=!word:~%var[10]%,1!
for %%y in (%alien%) do (echo|set /p =%%y)
pause > nul
endlocal disabledelayedexpasion
Layouts for screen display is seperated in mainly two cases. First case languages and second case to define possible changes.
The solution below is possible but it is not with an upgraded example to the main example.
#echo off
setlocal enabledelayedexpansion
for /f %%A in ('echo prompt $H ^| cmd') do set BS=%%A
set "string=XA THEWORDIZPAT"
for /L %%A in (0,1,14) do (
for /f "tokens=* delims=X" %%b in ("!string:~%%A,1!") do (
set /p=%BS%%%b < nul)
pause > nul
)

Remove a number of delimiters from each line of file

I have a file which I need to load into a database. It has a delimiter of pipe (|) however each line contains different number of pipes. Using a batch script, how can I remove pipes from each line so the same number of pipes are on each line?
Example of file:
1|2|3||||||
4|5|6|||
7|8||||||
Let's say I'd like 5 pipes on each line only so it looks like:
1|2|3|||
4|5|6|||
7|8||||
Update See second solution and limitation updates.
Example file.txt contents
A|B|C|D|E|F|G
1|2|3|4|5|6|7
!|#|#|$|%|^|&
]1|]2|]3|]4|]5|]6|]7
|Two||Four||||Eight
!#$%^&%^*(){}|[]';/.,<>/|
Lonely||||||||||||||||||
Sep|er|ate| From| Th|e |W||orld | |
First Solution
Here is a simple way to do what you want. It should not have any problems with special characters.
Limitations
It only supports up to 24 25 columns as it is currently written. %%A to %%Y
The first value may not begin with ]. Replaced for /F "tokens=1,* delims=]" %%Y in ('type file.txt ^| find /v /n ""') do ( with for /F "delims=" %%Z in ('type file.txt') do (.
"Empty" fields may only appear at the end of every line. See second solution.
Does not preserve blank lines in the file. (This can be fixed if desired.)
Just specify how many and which columns you want to keep. For example tokens=3-5,12,48-50 will select only columns 3,4,5,12,48,49,50. Make sure you add on or remove the variables to match the output you want. echo %%A^|%%B^|%%D^|%%C^|%%G^|%%E^|%%F. Note that the columns can be reordered as well in the echo statement.
#echo off
setlocal DisableDelayedExpansion
for /F "delims=" %%Z in ('type file.txt') do (
for /F "tokens=1-5 delims=|" %%A in ("%%Z") do (
echo %%A^|%%B^|%%C^|%%D^|%%E
)
)
endlocal
pause >nul
You can either redirect the output of the .bat file into a new file Script.bat>output.txt or output the echo command to a file by appending >>output.txt to the echo line.
Example Output:
A|B|C|D|E
1|2|3|4|5
!|#|#|$|%
]1|]2|]3|]4|]5
Two|Four|Eight|| <-- Note that this line exhibits limit 3.
!#$%^&%^*(){}|[]';/.,<>/|||
Lonely||||
Sep|er|ate| From| Th
Second Solution
Shares only limitations 1 and 4. Currently adds spaces into existing blank columns to preserve all columns. They can be removed with a further code change, but will not add unless desired by the OP.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "delims=" %%Z in ('type file.txt') do (
set "xLine=|%%Z"
call :Parse xLine
)
endlocal
pause >nul
goto :eof
:Parse
call set "xLine=%%%~1:||=| |%%"
for /F "tokens=1-5 delims=|" %%A in ("%xLine%") do (
echo %%A^|%%B^|%%C^|%%D^|%%E
)
goto :eof
Example Output:
A|B|C|D|E
1|2|3|4|5
!|#|#|$|%
]1|]2|]3|]4|]5
|Two| |Four|
!#$%^&%^*(){}|[]';/.,<>/|||
Lonely| | | |
Sep|er|ate| From| Th
There is no direct way to achieve this process, so each character must be revised in order to count the number of pipes in each line. It works, but it is somewhat slow.
#echo off
setlocal EnableDelayedExpansion
rem Number of desired pipes
set limit=5
for /F "delims=" %%a in (input.txt) do (
set "line=%%a"
rem Get position of last character
set last=0
for /L %%b in (12,-1,0) do (
set /A "last|=1<<%%b"
for %%c in (!last!) do if "!line:~%%c,1!" equ "" set /A "last&=~1<<%%b"
)
rem Copy each character to result, but just %limit% number of pipes
set pipes=0
set result=
for /L %%c in (0,1,!last!) do (
if "!line:~%%c,1!" neq "|" (
set "result=!result!!line:~%%c,1!"
) else (
set /A pipes+=1
if !pipes! leq %limit% set "result=!result!|"
)
)
echo !result!
)
Previous program will fail if the input line contain exclamation marks.
Output:
1|2|3|||
4|5|6|||
7|8||||
Antonio

Resources