Removing Items
[1/3] from: kvince1:attbi at: 3-Jul-2002 9:45
Greetings,
Simple question (hopefully). I'm reading from a very large quoted-comma
delimited text file and writing to a quoted-comma delimited text file.
I want to skip over the forty-first element and continue sending the
rest of the record to the outbound file. This would be repeated for
every record in the inbound file (over three hundred thousand).
Inbound: open/direct/lines %InboundTextFile.txt
Outbound: open/direct %OutboundTextFile.txt
Data: copy/part Inbound [find/skip {","} ** 41st element - part I don't
know how to do ** ]
Append Outbound Data
Any help would be appreciated!
Ken
[2/3] from: greggirwin:mindspring at: 3-Jul-2002 13:57
Hi Ken,
<< Simple question (hopefully). I'm reading from a very large quoted-comma
delimited text file and writing to a quoted-comma delimited text file.
I want to skip over the forty-first element and continue sending the
rest of the record to the outbound file. This would be repeated for
every record in the inbound file (over three hundred thousand). >>
REBOL's PARSE function is really good at splitting up data for you, but the
rest isn't *quite* so easy.
First, you can take the line of input (a string) and parse it into fields,
like so:
>> s: {a, b, "c, d, e", f, g}
== {a, b, "c, d, e", f, g}
>> parse s none
== ["a" "b" "c, d, e" "f" "g"]
Now you can remove field 41 very easily. I'll remove one item (at field
four) in my example here. Just replace 4 with 41 in your case.
>> head remove/part at parse s none 4 1
== ["a" "b" "c, d, e" "g"]
Now, it would be nice if REJOIN worked as a mirror of PARSE, but it doesn't,
as you can see below. It doesn't know about delimiters or fields that were
quoted in the original string.
>> rejoin head remove/part at parse s none 4 1
== "abc, d, eg"
To get around that, we can write a function to build a delimited string for
us without too much difficulty. I just coded this, without concern for
efficiency and very little testing. Caveat emptor.
make-dlm-str: func [
"Reduces and joins a block of values."
block [block!] "Values to reduce and join"
dlm [char! string!] "Delimiter to put between elements"
/local
mod-blk
][
mod-blk: make block! 2 * length? block
foreach item block [
append mod-blk reduce [
either find item dlm [mold item][item]
dlm
]
]
remove back tail mod-blk
rejoin mod-blk
]
Now we can do this, which looks OK to me:
>> make-dlm-str head remove/part at parse s none 4 1 ", "
== {a, b, "c, d, e", g}
This doesn't preserve the original formatting of course. If that's
important, or if you just want to tackle it a different way, you could use
PARSE in it's more powerful mode. E.g., as a starting point...
fld-sep: #","
valid-chars: complement charset ","
field: [
copy data [quoted-string | copy data some valid-chars] (print trim data)
[thru fld-sep | to end]
]
quoted-string: [{"} thru {"}]
rules: [some field to end]
>> s: {a, b, "c, d e", f, g}
>> parse s rules
(IANAPG - I Am Not A Parse Guru) so this quick example is likely flawed
somehow.
HTH!
--Gregg
[3/3] from: lmecir::mbox::vol::cz at: 3-Jul-2002 22:50
Hi Ken,
<<Ken>>
Simple question (hopefully). I'm reading from a very large quoted-comma
delimited text file and writing to a quoted-comma delimited text file.
I want to skip over the forty-first element and continue sending the
rest of the record to the outbound file. This would be repeated for
every record in the inbound file (over three hundred thousand).
Inbound: open/direct/lines %InboundTextFile.txt
Outbound: open/direct %OutboundTextFile.txt
Data: copy/part Inbound [find/skip {","} ** 41st element - part I don't
know how to do ** ]
Append Outbound Data
Any help would be appreciated!
<</Ken>>
How about:
line: first inbound
parse/all line [41 [thru #","] copy data to end]
etc.
-L