24} How do I get the m'th item on the n'th line of a text file?
The current question can be considered a refinement of getting the
n'th line which was considered in the previous
Item #23.
It is suggested that you first peruse that item.
Assume the following LFN-type test file: "My test file.txt"
word11 word12 word13 word14
word21 word22 "word23" (word24)
word31 word32 "word33" (word34)
word41 word42 "word43" (word44)
word51 word52 "word53" (word54)
word61 word62 "word63" (word64)
word71 word72 "word73" (word74)
word81 word82 "word83" (word84)
word91 word92 "word93" (word94)
A pure script solution, but the poison character and empty line problems (c.f.
Item #23).
@echo off & setlocal enableextensions
set myfile_=My test file.txt
set n=5
set m=3
call :ProcGetLine "%myfile_%" %n% getLine
for /f "tokens=%m%" %%? in ("%getLine%") do echo %%?
endlocal & goto :EOF
::
::===============================================================
:ProcGetLine FileName LineNro returnText
setlocal enableextensions
set return_=
if %2 GTR 1 goto _notFirst
for /f "tokens=* delims=" %%r in ('type %1') do (
if not defined return_ set return_=%%r)
endlocal & set "%~3=%return_%" & goto :EOF
:_notFirst
set lineNro_=%2
set /a lineNro_-=1
for /f "tokens=* skip=%lineNro_% delims=" %%r in ('type %1') do (
if not defined return_ set return_=%%r)
endlocal & set "%~3=%return_%" & goto :EOF
Since the fifth line in "My test file.txt" is
word51 word52 "word53" (word54)
the output will be
C:\_D\TEST>cmdfaq
"word53"
Getting the characters on line 5 starting from the third
ending with the eleventh characters would be easy:
Replace
for /f "tokens=%m%" %%? in ("%getLine%") do echo %%?
with
echo.%getLine:~2,9%
Note, however, the slight complication that the first argument
starts from zero and the second is the number of characters. Also
note the point (.) after the echo to prevent a potential "ECHO is
off." message. The output with, ruler indication lines added for
clarity, is
D:\TEST>cmdfaq
123456789 123456789 123456789
word51 word52 "word53" (word54)
word51 w
Another case:
> I have strings such as these:
> 'HELLO-1039-4019-3929'
> 'YES-1930-4910-4939'
> with a variable number of characters before the first hyphen. I'd
> like my command file to parse out and return to me the string
> 'HELLO' or 'YES': whatever exists before the first hyphen. Can
> someone point me in the right direction of how to do this? Thanks
> much.
@echo off & setlocal enableextensions
::
:: Make a test file
echo HELLO-1039-4019-3929 > mytest.txt
echo YES-1930-4910-4939 >> mytest.txt
::
::
for /f "tokens=1 delims=-" %%a in ('type mytest.txt') do (
echo %%a
)
::
:: Clean up
for %%f in (mytest.txt) do if exist %%f del %%f
endlocal & goto :EOF
The output:
C:\_D\TEST>cmdfaq
HELLO
YES
Return to the original task. With
G(nu)AWK
we get a more tolerant solution
@echo off & setlocal enableextensions
set myfile_=My test file.txt
set n=5
set m=3
for /f "tokens=* delims=" %%f in ("%myfile_%") do (
set myfile_=%%~sf)
gawk 'NR==%n% {printf "%%s\n",$%m%}' "%myfile_%"
endlocal & goto :EOF
The output will be
C:\_D\TEST>cmdfaq
"word53"
The renaming to a SFN-format
(
%%~sf)
is needed when the
G(nu)awk version originally assumed in this
FAQ is used.
@echo off & setlocal enableextensions
rem The same with GnuWin32 gawk (let's call it unxgawk)
set myfile_=My test file.txt
set n=5
set m=3
unxgawk "NR==%n% {printf \"%%s\n\",$%m%}" "%myfile_%"
endlocal & goto :EOF