Computing.Net > Forums > Programming > Batch read tab delim txt fil but do

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Over 90% answered within 24 hours! Click here to start participating now! Also, be sure to check out the New User Guide.

Batch read tab delim txt fil but do

Reply to Message Icon

Name: eriksson
Date: November 25, 2005 at 10:50:25 Pacific
OS: XP
CPU/Ram: P4
Comment:

Hello all greetings from Sweden! I have created a .bat file to read the contents of data.txt

data.txt consists of three columns each seperated with a tab:
col1 col2 col3

the structure of data.txt can not be changed.

So my script looks like:
for /f "tokens=1,2*" %%a in ('type data.txt') do (call :process "%%a" "%%b" "%%c")

This works fine, as long as there is data in each column. If for example co1um 1 is empty then the for loop puts the data from column 2 into column 1 (everything gets moved down one step).

I would like to prevent this from happening but I guess this is how the FOR loop works. Is there a way around this without changing the structure of data.txt?

Cheers




Sponsored Link
Ads by Google

Response Number 1
Name: Mechanix2Go
Date: November 25, 2005 at 12:18:10 Pacific
Reply:

Hi,

Depends on what the :process does.

I put this in data.txt:

one two three
four five six
eight nine

I tried this in:process:

:process

echo %1 %2 %3
if %1'==' (
echo.
else echo %1
)
if %2'==' (
echo.
else echo %1
)
if %3'==' (
echo.
else echo %1
)

goto :eof

Problem is, it doesn't know that seven is the first blank column so you get this:

"one" "two" "three"
"four" "five" "six"
"eight" "nine" ""


Beats me.

Good luck.


If at first you don't succeed, you're about average.

M2


0

Response Number 2
Name: dtech10
Date: November 25, 2005 at 15:40:05 Pacific
Reply:

Hi
Knowing what the Sub Process does might help
can the varables be passed as one string.

ie call :Process "one two three"
:Process "four TAB six"
:Process "TAB eight nine"


0

Response Number 3
Name: eriksson
Date: November 25, 2005 at 16:22:16 Pacific
Reply:

Hello, thanks for your ideas! Really sorry for the long post but I didn't explain good last time =)

The reason why I can't put like this "%%a %%b %%c" is because I need control over the content in each column (will later be outputed in a certain order, that's all) and so my FOR command must be "%%a" "%%b" "%%c".

I could do "%%a %%b %%c" instead but I would then have to parse it and I think this will give the same result?

Please bare with me, here is a better example of the problem.
data.txt looks like this:

col1<tab>col2<tab>col3
col1<tab>col2<tab>col3
col1<tab><tab>col3

So column 2 on the last row is empty, thats fine.
I can read the first two rows without any problem but look what happens in the last row:

ROW1 from data.txt
%%a=col1
%%b=col2
%%c=col3

ROW2 from data.txt
%%a=col1
%%b=col2
%%c=col3

ROW3 from data.txt
%%a=col1
%%b=col3
%%c=

So why does the content of column 3 move into column 2 in the last row? The answer to that will make me very happy. It's really ashame I can't change the structure of data.txt it would have been easier because the FOR command seems to have a life of it's own =)


0

Response Number 4
Name: Mechanix2Go
Date: November 25, 2005 at 17:29:52 Pacific
Reply:

"So why does the content of column 3 move into column 2 in the last row?"

I think it's as you said originally, the FOR gets it token by token. So if there are onlt two, they become a dn b.

As you said, getting the whole row in a string would require parsing and I think you'd wind up going in circles.

Is the data STRICTLY three columns? Albeit with some empty spots?


If at first you don't succeed, you're about average.

M2


0

Response Number 5
Name: Mechanix2Go
Date: November 25, 2005 at 17:49:21 Pacific
Reply:

This may help.

Not strictly a batch solution, but maybe a way forward.

The batch below saves the orig data.txt, makes a copy and uses CHANGE.COM, available here:

Change

to replace every ocurrance of a 'double tab' with [tab][BLANK][tab].

:: data4.bat
@echo off

copy data.txt data4.txt
change.com data4.txt 9,9 9,"BLANK",9
cls.

for /f "tokens=1,2*" %%a in ('type data4.txt') do (call :process "%%a" "%%b" "%%c")
goto :eof

:process

echo %1 %2 %3
goto :eof
:: DONE



If at first you don't succeed, you're about average.

M2


0

Related Posts

See More



Response Number 6
Name: FishMonger
Date: November 26, 2005 at 00:12:19 Pacific
Reply:

Would you be willing to use a language better suited for this task? Here's my test Perl script that first generates the test data file, then reads it back in and splits the lines on the tab char. Then I print it out using a debugging module so you can see each field, including the empty one.

#!/usr/bin/perl

use Data::Dumper;

open(F, '>erik.txt') or die $!;
print F "one\ttwo\tthree\n",
       "four\tfive\tsix\n",
       "seven\t\tnine\t\n";

close F;
open(F, '<erik.txt') or die $!;
while(<F>) {
    chomp;
    @fields = split /\t/;
    print "\nline $.\n";
    print Dumper @fields;
}

------

outputs:

line 1
$VAR1 = 'one';
$VAR2 = 'two';
$VAR3 = 'three';

line 2
$VAR1 = 'four';
$VAR2 = 'five';
$VAR3 = 'six';

line 3
$VAR1 = 'seven';
$VAR2 = '';
$VAR3 = 'nine';


0

Response Number 7
Name: eriksson
Date: November 26, 2005 at 05:55:38 Pacific
Reply:

Tack så mycket Mechanix2Go!
Thanks in Swedish Mechanix2Go, your solution works. Altought I don't understand the code.

This is syntax right?:
change.com "stringold" "stringnew"

So what does your code do (what do the 9's and commas do?):
change.com data4.txt 9,9 9,"BLANK",9

I would have liked to have it work without any extra files (change.com) but since it works with change.com I'm happy anyway =)

FishMonger, I don't know perl so I couldn't try this but thanks for providing it! Does Perl have to be installed in users computer or how does it execute your code?


0

Response Number 8
Name: dtech10
Date: November 26, 2005 at 07:20:19 Pacific
Reply:

Hi
Try this without Change.com

@echo off
SetLocal EnableDelayedExpansion

find /n /v "" Tabs.txt > ~Tmp1.txt
type nul > ~Tmp2.txt
for /f "tokens=*" %%a in (~Tmp1.txt) do (
set Line=%%a
set Line=!Line: =" "!
echo !Line! >> ~Tmp2.txt
)


for /f "skip=1 tokens=1-4 delims=[]" %%a in (~Tmp2.txt) do call :Process "%%b" "%%c" "%%d"
del ~Tmp?.txt
SetLocal
exit /b

:Process %1 %2 %3
echo Arg1=%1
echo Arg2=%2
echo Arg3=%3
echo.
pause > nul



0

Response Number 9
Name: FishMonger
Date: November 26, 2005 at 07:21:40 Pacific
Reply:

Usually the Perl interpretor is installed on the user's computer, but it doesn't need to be. The Perl script can be compiled into a standalone executable.


0

Response Number 10
Name: eriksson
Date: November 26, 2005 at 07:56:42 Pacific
Reply:

Hi dtech10! This works great but the output is not controllable; everything is placed into one single variable %1.

This is what I did:

source.txt
row1col1<tab>row1col2<tab>row1col3
row2col1<tab><tab>row2col3
row3col1<tab>row3col2<tab>row3col3

output.txt with your code
"row1col1<tab>row1col2<tab>row1col3 "
"row2col1<tab><tab>row2col3 "
"row3col1<tab>row3col2<tab>row3col3 "

As you can see this is very good, nothing gets moved as before. However, as you can see each row is surrounded by "" and that's because each row is contained in one variable as I mentioned before (echo:ing %1)

This means I have to parse each row, again, which of course gives the same problem as before.

So what I'm saying is THANKS =) and do you know how to better control the output from your code?

Thanks all for helping out!!


0

Response Number 11
Name: eriksson
Date: November 26, 2005 at 08:02:08 Pacific
Reply:

FishMonger I would like to give your script a go!

Can you give me a hint on what I need to download to be able to compile your script into an .exe? Are we talking free software still?

Cheers


0

Response Number 12
Name: dtech10
Date: November 26, 2005 at 08:23:03 Pacific
Reply:

Hi
Sorry I forgot to mension the space is a TAB

find /n /v "" Tabs.txt > ~Tmp1.txt
type nul > ~Tmp2.txt
for /f "tokens=*" %%a in (~Tmp1.txt) do (
set Line=%%a
set Line=!Line:TAB=" "!
echo !Line! >> ~Tmp2.txt
)



0

Response Number 13
Name: FishMonger
Date: November 26, 2005 at 08:47:32 Pacific
Reply:

First, you need to install Perl, which is free and open source.
http://www.activestate.com/Products/ActivePerl/?mp=1

It's not required, but I'd recommend using an IDE, such as Komodo for writing/testing/debugging scripts. You can download and use it for a 21 day free trial.
http://www.activestate.com/Products/Komodo/?utm_source=activeperl&utm_medium=banner&utm_campaign=komodo_activeperl_page

Additional Windows Perl ports and IDE's
http://cpan.org/ports/index.html#win32

Compiling Perl scripts:
Perl2Exe
http://www.indigostar.com/perl2exe.htm

PAR
http://search.cpan.org/~autrijus/PAR-0.89/lib/PAR.pm


0

Response Number 14
Name: eriksson
Date: November 26, 2005 at 09:21:06 Pacific
Reply:

sorry dtech10 i missed that, it works fine now. Muchas gracias all!

will you rip my head off if i asked for a small alternation of the script =)? I just noticed something obvious that I missed.

This script works fine for:
col1<tab>col2<tab>col3

but does not work for:
col1<tab><tab><tab>col2<tab>col3

What I was looking for was for the later to work also - that is it shouldn't matter how many TABs are inbetween as long as the content (that isn't a TAB) gets put in variables col1 col2 and col3.

Thanks FishMonger for the perl stuff I'm looking forward to learning some perl as soon as possible!


0

Response Number 15
Name: Mechanix2Go
Date: November 26, 2005 at 09:29:47 Pacific
Reply:

The syntax dor change.com is:

change.com filename.ext "old" "new"

[separated by SINGLE spaces]

or:

change.com filename.ext aa,bb cc,dd

[where aa bb cc dd are DECIMAL bytes]

or a combination of the two. So in my script, a [tab][tab] gets the string inserted. In the above case, BLANK.

You wi;l, of course, want to choose a string which is NOT one of you data elements.

I understand not wanting to use any third party utilities. But because of the way the batch interpreter is wired, I see no way around.

If you need to 'distribute' this script, we could include code to create change.com on the fly.

Hi FishMonger,

I got a bunch of errors when I ran your perl script.


If at first you don't succeed, you're about average.

M2


0

Response Number 16
Name: AKL-MFCU
Date: November 26, 2005 at 09:45:51 Pacific
Reply:

Crazy question, but why so much emphasis on tabbing? Couldn't you use comma seperated values and have it be categorized by that? Just wondering...


0

Response Number 17
Name: eriksson
Date: November 26, 2005 at 09:47:45 Pacific
Reply:

Mechanix2Go that would be great if you could publish or point to the code for writing change.com from a .bat file (on the fly as you say).

I admit using change.com was a bit easier for me and perhaps it will be easier to adapt the script with change.com to do both my wishes:

source example1
col1<tab><tab><tab>col2<tab>col3

source example2
col1<tab>col2<tab>col3

/B


0

Response Number 18
Name: eriksson
Date: November 26, 2005 at 09:53:19 Pacific
Reply:

AKL-MFCU
Yes i know it's wierd. I use a PLC software called MEDOC. One can import a list of settings (in my case data.txt) to this program only if the structure is content<tab>content<tab>

Now, the reason I want to read data.txt and parse it is because I wish to publish this data in a controlled way to another program or a report or whatever.


0

Response Number 19
Name: FishMonger
Date: November 26, 2005 at 09:57:39 Pacific
Reply:

M2,

Are you sure you copied it correctly?
---

C:\temp>dir /b
eriksson.pl

C:\temp>type eriksson.pl
#!/usr/bin/perl -w

use Data::Dumper;

open(F, '>erik.txt') or die $!;
print F "one\ttwo\tthree\n",
"four\tfive\tsix\n",
"seven\t\tnine\t\n";

close F;
open(F, '<erik.txt') or die $!;
while(<F>) {
chomp;
@fields = split /\t/;
print "\nline $.\n";
print Dumper @fields;
}
C:\temp>eriksson.pl

line 1
$VAR1 = 'one';
$VAR2 = 'two';
$VAR3 = 'three';

line 2
$VAR1 = 'four';
$VAR2 = 'five';
$VAR3 = 'six';

line 3
$VAR1 = 'seven';
$VAR2 = '';
$VAR3 = 'nine';

C:\temp>dir /b
erik.txt
eriksson.pl

C:\temp>type erik.txt
one two three
four five six
seven nine

---

This forum is very frustrating when posting code or its output. Justin is a little over zealous about stripping the spaces and tabs.


0

Response Number 20
Name: Mechanix2Go
Date: November 26, 2005 at 10:31:39 Pacific
Reply:

Hi FM,

Evidently I didn't. I copied the above and it flew.

AKL,

Even if he could change to csv, he'd be back in the same can of worms with shifting tokens caused by empty cells.

eriksson,

I'll work up the bat to create change.com and get back to you.


If at first you don't succeed, you're about average.

M2


0

Response Number 21
Name: eriksson
Date: November 26, 2005 at 10:35:02 Pacific
Reply:

Sounds really great cheers!


0

Response Number 22
Name: FishMonger
Date: November 26, 2005 at 10:45:32 Pacific
Reply:

eriksson and M2,

Check your email. I sent you a compiled version.


0

Response Number 23
Name: Mechanix2Go
Date: November 26, 2005 at 11:24:04 Pacific
Reply:

make change


Hi FM,

Looks like it got filtered; probably because it had a ZIP. Could you rename to .FM and resend.

I DL'd that perl2exe and I'll fire it up asap. TY


If at first you don't succeed, you're about average.

M2


0

Response Number 24
Name: eriksson
Date: November 26, 2005 at 11:43:56 Pacific
Reply:

FishMonger, it got filtered here also resend to me also please =)


0

Response Number 25
Name: dtech10
Date: November 27, 2005 at 18:03:20 Pacific
Reply:

Hi eriksson
Will this do for now until I figure a better way.

@echo off
SetLocal EnableDelayedExpansion

find /n /v "" Tabs.txt > ~Tmp1.txt
type nul > ~Tmp2.txt
for /f "tokens=*" %%a in (~Tmp1.txt) do (
set Line=%%a
set Line=!Line: =" "!
echo !Line! >> ~Tmp2.txt
)


for /f "skip=1 tokens=1-9 delims=[]" %%a in (~Tmp2.txt) do call :Process "%%b" "%%c" "%%d" "%%e" "%%f" "%%g" "%%h" "%%i%"
del ~Tmp?.txt
SetLocal
exit /b

:Process %1 %2 %3 %4 %5 %6 %7 %8 %9
set Arg1=%1
set Arg2=%2
set Arg3=%3
set Arg4=%4
set Arg5=%5
set Arg6=%6
set Arg7=%7
set Arg8=%8
set Arg9=%9
set Count=0
for /l %%a in (1,1,9) do (
if not !Arg%%a!=="" set /a Count+=1
)
if !Count! GTR 2 (
set Count=1
for /l %%a in (1,1,9) do (
if not !Arg%%a!=="" (
if !Count! LSS 4 (
set Arg!Count!=!Arg%%a!
set /a Count+=1
)
)
)
)
echo Par1=!Arg1!
echo Par2=!Arg2!
echo Par3=!Arg3!
echo.
pause > nul


0

Response Number 26
Name: FishMonger
Date: November 27, 2005 at 23:19:49 Pacific
Reply:

Is this the expected output of your batch script?

C:\temp>dtech10.bat
Par1="one two three "
Par2=""
Par3=""

Par1="four five six "
Par2=""
Par3=""

Par1="seven nine "
Par2=""
Par3=""

---

Here's a Perl command that outputs what I think you expected.

C:\temp>perl -F/\t/ -MData::Dumper -lane "print Dumper @F;" Tabs.txt
$VAR1 = 'one';
$VAR2 = 'two';
$VAR3 = 'three';

$VAR1 = 'four';
$VAR2 = 'five';
$VAR3 = 'six';

$VAR1 = 'seven';
$VAR2 = '';
$VAR3 = 'nine';


0

Response Number 27
Name: Mechanix2Go
Date: November 27, 2005 at 23:40:05 Pacific
Reply:

KEWL


If at first you don't succeed, you're about average.

M2


0

Response Number 28
Name: FishMonger
Date: November 27, 2005 at 23:56:07 Pacific
Reply:

Yep I agree, it's very KEWL :)

That is the while loop I posted earlier, executed from the command line instead of the script.


0

Response Number 29
Name: Mechanix2Go
Date: November 28, 2005 at 00:00:36 Pacific
Reply:

FM,

Yep, for my diseased mind, simpler is better.

This thread, unlike many high milers, has prodiced more light than heat.


If at first you don't succeed, you're about average.

M2


0

Response Number 30
Name: dtech10
Date: November 28, 2005 at 05:51:50 Pacific
Reply:

Hi Fishmonger
Not Quite.
As I explaned to Eric earlier the here is
a TAB
@echo off
SetLocal EnableDelayedExpansion

find /n /v "" Tabs.txt > ~Tmp1.txt
type nul > ~Tmp2.txt
for /f "tokens=*" %%a in (~Tmp1.txt) do (
set Line=%%a
rem The Space here is a TAB
set Line=!Line:TAB=" "!
echo !Line! >> ~Tmp2.txt
)



0

Response Number 31
Name: eriksson
Date: November 28, 2005 at 07:52:50 Pacific
Reply:

dtech10, FishMonger, Mechanix2Go - Thank you all for your time and effort! I have more than one solution, I'm over the moon (you can imagine)!

perl -F/\t/ -MData::Dumper -lane "print Dumper @F;" Tabs.txt

Wow Perl is effective. I have to learn more about it, googling for tutorials. It looks alot like javascript from what I've read so far - easy to follow hopefully.
Guess it will take a while until I can create my own tabs.exe, but I have time =)

Simma lugnt!
Swedish for "take it easy" or translating word by word which is more fun: "Swim calmly"


0

Response Number 32
Name: Mechanix2Go
Date: November 28, 2005 at 08:09:48 Pacific
Reply:

Maybe we can get FM to teach a crash course.

dtech 10,

I made one small change to eliminate the:

---------- TABS.TXT

:: d10a.bat
@echo off
SetLocal EnableDelayedExpansion

find /n /v "" < Tabs.txt > ~Tmp1.txt
type nul > ~Tmp2.txt
for /f "tokens=*" %%a in (~Tmp1.txt) do (
set Line=%%a
rem The Space here is a TAB
set Line=!Line:TAB=" "!
echo !Line! >> ~Tmp2.txt
)
:: DONE


If at first you don't succeed, you're about average.

M2


0

Response Number 33
Name: FishMonger
Date: November 28, 2005 at 12:16:19 Pacific
Reply:

>> Maybe we can get FM to teach a crash course.

lol, I thought that was what I was doing; especially when I butt-in on these batch file questions. :-)


0

Response Number 34
Name: dtech10
Date: November 29, 2005 at 06:53:35 Pacific
Reply:

Hi
Thanks Mechanix every little bit helps.
I think I need to stop looking at the site.
Im geeting RSI from all these batch files.
Maybe I swat up a bit more and make life easier by learning Perl, VBA, anything but MsDos Batch files, even Unix Shell was easier.


0

Sponsored Link
Ads by Google
Reply to Message Icon

CScokets problem in C++ attn: dtech10 ; oneline.c...



Post Locked

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.


Go to Programming Forum Home


Sponsored links

Ads by Google


Results for: Batch read tab delim txt fil but do

Read lines from .txt file in DOS? www.computing.net/answers/programming/read-lines-from-txt-file-in-dos/15219.html

BATCH reading structured Text File www.computing.net/answers/programming/batch-reading-structured-text-file/14544.html

Read vaiable from txt file www.computing.net/answers/programming/read-vaiable-from-txt-file/19350.html