Return character of specific position in a line

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
CMOS
Posts: 8
Joined: 23 May 2013 14:21

Return character of specific position in a line

#1 Post by CMOS » 11 Jun 2013 12:33

Is it possible, using a batch file, to determine what character is in a certain position of a line in a text file?

So if I have a text file and I want to check what character is in position 10 and perform a correlating function based on the result of the line, how can I do that?

There are several possible variations of what could in that position, I believe around 10. It's only one character in length as well, so I couldn't find a way to make it work with Findstr. Output would need to match the original formatting as well.

Any help would be appreciated.

Thank you.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Return character of specific position in a line

#2 Post by aGerman » 11 Jun 2013 14:45

There are several possibilities.

Try

Code: Select all

@echo off &setlocal
call :getchar "test.txt" 2 5 char
if errorlevel 1 echo ERROR!
echo %char%
pause
goto :eof

:getchar  fname_in  line_in  position_in  char_out
set "%~4="
setlocal EnableExtensions DisableDelayedExpansion
set "file=%~1"
set /a "line=%~2, pos=%~3 - 1"
for /f %%i in ('type "%file%"^|find /c /v ""') do set /a "max=%%i"
if %line% gtr %max% (endlocal &exit /b 1)
<"%file%" (for /l %%i in (1 1 %line%) do (set "txt=" &set /p "txt="))
setlocal EnableDelayedExpansion
if "!txt!"=="" (endlocal &endlocal &exit /b 1)
set "char=!txt:~%pos%,1!"
if "!char!"=="" (endlocal &endlocal &exit /b 1)
endlocal &endlocal &set "%~4=%char%" &exit /b 0


The function assigns the 5th character of line 2 in test.txt to the variable char.

Regards
aGerman

EDIT pos=%~3 + 1 TO pos=%~3 - 1

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Return character of specific position in a line

#3 Post by Aacini » 11 Jun 2013 14:52

Your question is too vague. You may directly extract the character at position 10 via Batch substring extraction:

Code: Select all

set line=ABCDEFGHIJKLMN
set charAt10=%line:~9,1%

About correlating one value to another one, my favorite method is via an array:

Code: Select all

set relate[A]=Value related to A
set relate[B]=Value related to B
. . .
set relate[J]=Value related to J

echo The value related to %charAt10% is !relate[%charAt10%]!

Perhaps if you explain more clearly your problem we may help you in a better way...

Antonio

CMOS
Posts: 8
Joined: 23 May 2013 14:21

Re: Return character of specific position in a line

#4 Post by CMOS » 11 Jun 2013 17:22

Sorry for the ambiguity, I'll try and explain better.

I have text files (and receive more daily) that contain a varying number of lines, some nights it could be 400, others 387, others 245, etc... Each line contains 1000 characters and is formatted in a specific fashion. The 10th character of each line determines how I use the information contained in that line. So what I'd like to do is search each line of the file, determine the 10th character of the line and then if it matches the desired character (say A), take that entire line of information out of the text file and put it into a second text file in the same format.

Hopefully I did a better job explaining. I appreciate the assistance so far!

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Return character of specific position in a line

#5 Post by aGerman » 11 Jun 2013 17:43

Something like that should work:

Code: Select all

@echo off &setlocal

set "infile=in.txt"
set "outfile=out.txt"
set "char=A"
set "pos=10"

setlocal EnableDelayedExpansion
set /a "pos -= 1"
<"!infile!" >"!outfile!" (
  for /f %%i in ('type "!infile!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (
    set "line=" &set /p "line="
    if defined line if "!line:~%pos%,1!"=="!char!" echo(!line!
  )
)

Regards
aGerman

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Return character of specific position in a line

#6 Post by Aacini » 11 Jun 2013 19:14

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem I have text files (and receive more daily) that contain a varying number of lines
(for %%a in (*.txt) do (

   rem Each line contains 1000 characters
   rem I'd like to do is search each line of the file,
   for /F "usebackq delims=" %%b in ("%%a") do (
     
      rem if the 10th character of the line matches the desired character (say A)
      set "line=%%b"
      if "!line:~9,1!" equ "A" (

         rem take that entire line of information out of the text file
         echo !line!

      )
   )

rem and put it into a second text file in the same format.
)) > secondFile.txt


I hope it helps!

Antonio

CMOS
Posts: 8
Joined: 23 May 2013 14:21

Re: Return character of specific position in a line

#7 Post by CMOS » 12 Jun 2013 10:11

Aacini wrote:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem I have text files (and receive more daily) that contain a varying number of lines
(for %%a in (*.txt) do (

   rem Each line contains 1000 characters
   rem I'd like to do is search each line of the file,
   for /F "usebackq delims=" %%b in ("%%a") do (
     
      rem if the 10th character of the line matches the desired character (say A)
      set "line=%%b"
      if "!line:~9,1!" equ "A" (

         rem take that entire line of information out of the text file
         echo !line!

      )
   )

rem and put it into a second text file in the same format.
)) > secondFile.txt


I hope it helps!

Antonio


Thank you both for the assistance. The quoted code worked great save one issue I'm having... as mentioned the value of the 10th character determines how the line is used. So I added more IF statements to match the characters (A through E). This part seems to work fine as any lines matching that indicator get moved into the desired text file. However, all the lines that don't match need to get moved to a different text file as well. I didn't think I had to have all the comparisons again (ie. line ~9,1 NEQ "A") but an added else statement is not providing the desired results.

What am I missing?

Thanks again.

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Return character of specific position in a line

#8 Post by Squashman » 12 Jun 2013 10:58

How about posting your revised code?

CMOS
Posts: 8
Joined: 23 May 2013 14:21

Re: Return character of specific position in a line

#9 Post by CMOS » 12 Jun 2013 14:06

Squashman wrote:How about posting your revised code?


Sure...

Code: Select all

@echo off
setlocal EnableDelayedExpansion

(for %%a in (*.txt) do (

     for /F "usebackq delims=" %%b in ("%%a") do (
     
      set "line=%%b"
      if "!line:~9,1!" equ "A" (
         echo !line!
      )
      if "!line:~9,1!" equ "B" (
         echo !line!
      )
      if "!line:~9,1!" equ "C" (
         echo !line!
      )
     if "!line:~9,1!" equ "D" (
         echo !line!
      )
     if "!line:~9,1!" equ "E" (
         echo !line!
      )

   )
)) > secondFile.txt


This seems to work; if the 10th character matches any of those letters it echos the contents of that line to a textfile. Because batch files don't support OR (at least I couldn't find any syntax or example of it), I'm not sure how to write my IF statement so the code iterates through each if statement and then if the 10th character doesn't match that code to the redirect that output to a different textfile. Ideally, it would be If (in relative psuedo code) x equ "A" or "B" or "C" etc.. echo line to file A else echo line to file B.

Thanks in advance.

Acy Forsythe
Posts: 126
Joined: 10 Jun 2011 10:30

Re: Return character of specific position in a line

#10 Post by Acy Forsythe » 12 Jun 2013 14:32

Try this if you want to separate the files. Using nested IF/ELSE can get a little convoluted, so I'd stick to the multiple IF statements until you feel more comfortable...

Code: Select all

@echo off
setlocal EnableDelayedExpansion

(for %%a in (*.txt) do (

     for /F "usebackq delims=" %%b in ("%%a") do (
     
      set "line=%%b"
      if "!line:~9,1!" equ "A" (
         echo !line!
    Set "FileName=FileA"
      )
      if "!line:~9,1!" equ "B" (
         echo !line!
    Set "FileName=FileB"
      )
      if "!line:~9,1!" equ "C" (
         echo !line!
    Set "FileName=FileC"
      )
     if "!line:~9,1!" equ "D" (
         echo !line!
         Set "FileName=FileD"
      )
     if "!line:~9,1!" equ "E" (
         echo !line!
         Set "FileName=FileE"
      )

   )
)) > %FileName%.txt

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Return character of specific position in a line

#11 Post by Aacini » 12 Jun 2013 14:48

It is a very bad practice to develop a program in "little steps" (when requirement A is fulfilled, request requirement B; when it is fulfilled request the C and so on) because is frequent that a posterior modification entirely replaces a previous one, so our efforts in the development of such modifications is wasted. The best programs are developed fulfilling complete requirements.

The Batch file below check if the 10th character is anyone of A through E and send the line to secondFile.txt if the answer is true, otherwise the line is sent to differentFile.txt:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set matchingChars=ABCDE
del secondFile.txt 2> NUL
del differentFile.txt 2> NUL

rem I have text files (and receive more daily) that contain a varying number of lines
for %%a in (*.txt) do (

   rem Each line contains 1000 characters
   rem I'd like to do is search each line of the file,
   for /F "usebackq delims=" %%b in ("%%a") do (
     
      rem if the 10th character of the line is anyone of matchingChars
      set "line=%%b"
      for %%c in ("!line:~9,1!") do set "matchedChars=!matchingChars:%%~c=!"
      if "!matchedChars!" neq "%matchingChars%" (

         rem take that entire line of information out of the text file
         rem and put it into a second text file in the same format.
         echo !line!>> secondFile.txt

      ) else (

         rem the lines that don't match need to get moved to a different text file
         echo !line!>> differentFile.txt

      )
   )

)


Antonio

CMOS
Posts: 8
Joined: 23 May 2013 14:21

Re: Return character of specific position in a line

#12 Post by CMOS » 18 Jun 2013 09:08

Aacini wrote:It is a very bad practice to develop a program in "little steps" (when requirement A is fulfilled, request requirement B; when it is fulfilled request the C and so on) because is frequent that a posterior modification entirely replaces a previous one, so our efforts in the development of such modifications is wasted. The best programs are developed fulfilling complete requirements.

The Batch file below check if the 10th character is anyone of A through E and send the line to secondFile.txt if the answer is true, otherwise the line is sent to differentFile.txt:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set matchingChars=ABCDE
del secondFile.txt 2> NUL
del differentFile.txt 2> NUL

rem I have text files (and receive more daily) that contain a varying number of lines
for %%a in (*.txt) do (

   rem Each line contains 1000 characters
   rem I'd like to do is search each line of the file,
   for /F "usebackq delims=" %%b in ("%%a") do (
     
      rem if the 10th character of the line is anyone of matchingChars
      set "line=%%b"
      for %%c in ("!line:~9,1!") do set "matchedChars=!matchingChars:%%~c=!"
      if "!matchedChars!" neq "%matchingChars%" (

         rem take that entire line of information out of the text file
         rem and put it into a second text file in the same format.
         echo !line!>> secondFile.txt

      ) else (

         rem the lines that don't match need to get moved to a different text file
         echo !line!>> differentFile.txt

      )
   )

)


Antonio


I wanted to follow up on this and say thank you for the help. The provided code above worked great.

Can someone explain, or share a link that explains, the difference between %variable% and !variable! ?

Thanks again.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Return character of specific position in a line

#13 Post by foxidrive » 18 Jun 2013 22:01

CMOS wrote:Can someone explain, or share a link that explains, the difference between %variable% and !variable! ?


The !variable! is used when delayed expansion is in effect

Google on setlocal and enabledelayedexpansion


CMOS
Posts: 8
Joined: 23 May 2013 14:21

Re: Return character of specific position in a line

#15 Post by CMOS » 20 Jun 2013 13:45

Thank you for the links... I believe I'm starting to get it.

With that said, I'm curious if given the same information given above if there's a way to extract the previous and subsequent line after finding a matching character? It's not entirely necessary but I'm interesting in if there are methods to cycle through the data within the loop?

Thank you.

Post Reply