Thread View: comp.unix.shell
12 messages
12 total messages
Started by Mark A Monroe
Tue, 11 Sep 1990 13:42
Breaking large file into pieces
Author: Mark A Monroe
Date: Tue, 11 Sep 1990 13:42
Date: Tue, 11 Sep 1990 13:42
39 lines
1779 bytes
1779 bytes
I want to rip a large file into pieces, naming new files according
to an ID string in the large file. For example, the large file contains
records that look like this:
xxx-00001239 data data data
description
.
.
(variable length)
.
<---blank line
xxx-00001489 data data data
description
.
.
(variable length)
.
<---blank line
xxx-00001326 data data data
When I find a line in the large data file that starts
with "xxx-0000", I want to open a file named "xxx-0000<number>",
like "xxx-00001489", and write every line, including
the current one, into it. When I see another "xxx-0000",
I want to close the file, open a new file named for the new id
string, and continue writing. At the end of the large data
file, close all files and exit.
Any suggestions?
--
-------------------------- END OF MAIN MESSAGE -----------------------------
Mark A. Monroe
UNIX Release Integration Internet: monroe@dg-rtp.dg.com
Data General Corp. UUCP: {world}!mcnc!rti!dg-rtp!monroe
Research Triangle Park, NC Phone: (919)248-6234
----------------------------------------------------------------------------
Re: Breaking large file into pieces
Author: Larry Wall
Date: Tue, 11 Sep 1990 19:38
Date: Tue, 11 Sep 1990 19:38
57 lines
2344 bytes
2344 bytes
In article <1990Sep11.134238.20218@dg-rtp.dg.com> monroe@dg-rtp.dg.com (Mark A Monroe) writes:
: I want to rip a large file into pieces, naming new files according
: to an ID string in the large file. For example, the large file contains
: records that look like this:
:
: xxx-00001239 data data data
: description
: .
: .
: (variable length)
: .
: <---blank line
: xxx-00001489 data data data
: description
: .
: .
: (variable length)
: .
: <---blank line
: xxx-00001326 data data data
:
: When I find a line in the large data file that starts
: with "xxx-0000", I want to open a file named "xxx-0000<number>",
: like "xxx-00001489", and write every line, including
: the current one, into it. When I see another "xxx-0000",
: I want to close the file, open a new file named for the new id
: string, and continue writing. At the end of the large data
: file, close all files and exit.
:
: Any suggestions?
In standard shell+awk+sed it's a bit hard because you run out of file
descriptors. You could do something like run sed over your file
to turn it into a giant script of here-is commands, but that'll be
real slow.
You could do something like this:
while read line; do
case "$line" in
xxx-0000*) set $line; exec >$1;;
esac
echo "$line"
done
But how well that works depends on the vagaries of your echo command,
such as what it does with lines starting with '-', or containing '\c'.
You don't really want to do this on a machine where echo isn't a builtin.
If you have Perl, your fastest solution will be to say something like
perl -pe 'open(STDOUT,">$&") if /^xxx-0000\d+/' filename
Change > to >> if the keys aren't unique in your input file.
Larry Wall
lwall@jpl-devvax.jpl.nasa.gov
Re: Breaking large file into pieces
Author: Randal Schwartz
Date: Tue, 11 Sep 1990 20:05
Date: Tue, 11 Sep 1990 20:05
46 lines
2255 bytes
2255 bytes
In article <1990Sep11.134238.20218@dg-rtp.dg.com>, monroe@dg-rtp (Mark A Monroe) writes: | I want to rip a large file into pieces, naming new files according | to an ID string in the large file. For example, the large file contains | records that look like this: | | xxx-00001239 data data data | description | . | . | (variable length) | . | <---blank line | xxx-00001489 data data data | description | . | . | (variable length) | . | <---blank line | xxx-00001326 data data data | | When I find a line in the large data file that starts | with "xxx-0000", I want to open a file named "xxx-0000<number>", | like "xxx-00001489", and write every line, including | the current one, into it. When I see another "xxx-0000", | I want to close the file, open a new file named for the new id | string, and continue writing. At the end of the large data | file, close all files and exit. | | Any suggestions? You didn't say "and I don't want it in Perl", so I'm considering this solution fair game... perl -pe 'open(STDOUT,">$1") if /^(xxx-\d+)/;' bigdatafile Pretty durn simple. The right tool for the job. Yeah, you could do it with an awk script feeding into a /bin/sh (or with a smarter awk), but this is too easy. Just another Perl hacker, -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
Re: Breaking large file into pieces
Author: Dan Bernstein
Date: Tue, 11 Sep 1990 21:10
Date: Tue, 11 Sep 1990 21:10
7 lines
681 bytes
681 bytes
In article <9466@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: > echo "$line" C'mon, Larry. You know that should be echo -n "$line$n" where $n has been initialized to a newline. Or echo -n "$line"; echo. ---Dan
Re: Breaking large file into pieces
Author: Parag Shah
Date: Tue, 11 Sep 1990 21:14
Date: Tue, 11 Sep 1990 21:14
13 lines
883 bytes
883 bytes
>I want to rip a large file into pieces, naming new files according >to an ID string in the large file. For example, the large file contains >records that look like this: >xxx-00001239 data data data >description Seems like the "csplit" command may be able to help you. You may have to rename the namely created files later using the first line to get the number id that you want. Parag
Re: Breaking large file into pieces
Author: Larry Wall
Date: Tue, 11 Sep 1990 22:16
Date: Tue, 11 Sep 1990 22:16
13 lines
1096 bytes
1096 bytes
In article <22842:Sep1121:10:3390@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: : In article <9466@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: : > echo "$line" : : C'mon, Larry. You know that should be echo -n "$line$n" where $n has : been initialized to a newline. Or echo -n "$line"; echo. Don't teach your grandmother to suck eggs. Let's see you come up with a solution that also works on all the \c machines. Apart from "Install SVR4". :-) Larry
Re: Breaking large file into pieces
Author: Tim.Ouellette
Date: Wed, 12 Sep 1990 08:08
Date: Wed, 12 Sep 1990 08:08
51 lines
2262 bytes
2262 bytes
>>>>> On 11 Sep 90 13:42:38 GMT, monroe@dg-rtp.dg.com (Mark A Monroe) said:
Mark> I want to rip a large file into pieces, naming new files according
Mark> to an ID string in the large file. For example, the large file contains
Mark> records that look like this:
Mark> xxx-00001239 data data data
Mark> description
Mark> .
Mark> .
Mark> (variable length)
Mark> .
Mark> <---blank line
Mark> xxx-00001489 data data data
Mark> description
Mark> .
Mark> .
Mark> (variable length)
Mark> .
Mark> <---blank line
Mark> xxx-00001326 data data data
Mark> When I find a line in the large data file that starts
Mark> with "xxx-0000", I want to open a file named "xxx-0000<number>",
Mark> like "xxx-00001489", and write every line, including
Mark> the current one, into it. When I see another "xxx-0000",
Mark> I want to close the file, open a new file named for the new id
Mark> string, and continue writing. At the end of the large data
Mark> file, close all files and exit.
Mark,
Here's an awk solution.
------------------------split.awk-----------------------
BEGIN{pcFile="/dev/null";}
/xxx-[0123456789]+/{close(pcFile);pcFile = $1;}
{print $0 >> pcFile;}
--------------------------------------------------------
execute it by
awk -f split.awk datafile
Hope this helps
--
Timothy R. Ouellette
NCR Microelectronics Tim.Ouellette@FtCollins.ncr.com
Ft. Collins, CO. uunet!ncrlnk!ncr-mpd!bach!timo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"If all the world is a stage, I want to run the trap door" -- P. Beaty
Re: Breaking large file into pieces
Author: 4197,ATTT
Date: Wed, 12 Sep 1990 12:46
Date: Wed, 12 Sep 1990 12:46
43 lines
1781 bytes
1781 bytes
In article <1990Sep11.134238.20218@dg-rtp.dg.com> monroe@dg-rtp.dg.com (Mark A Monroe) writes:
>I want to rip a large file into pieces, naming new files according
>to an ID string in the large file. For example, the large file contains
>records that look like this:
>
>xxx-00001239 data data data
>description
> .
> .
>(variable length)
> .
> <---blank line
>xxx-00001489 data data data
>description
> .
> .
>(variable length)
> .
> <---blank line
>xxx-00001326 data data data
>
>When I find a line in the large data file that starts
>with "xxx-0000", I want to open a file named "xxx-0000<number>",
>like "xxx-00001489", and write every line, including
>the current one, into it. When I see another "xxx-0000",
>I want to close the file, open a new file named for the new id
>string, and continue writing. At the end of the large data
>file, close all files and exit.
>
>Any suggestions?
Use context split "csplit(1)" to break up the file efficiently. Then
use head/cut/mv to rename the pieces.
csplit -f aaa /"^xxx-0000"/ {99} <in-file-name>
rm aaa00
for FN in `ls aaa*`
do
NFN=`head -1 $FN | cut -d' ' -f1 `
mv $FN $NFN
done
Bob Rager
Re: Breaking large file into pieces
Author: WU SHI-KUEI
Date: Wed, 12 Sep 1990 18:48
Date: Wed, 12 Sep 1990 18:48
1 lines
583 bytes
583 bytes
The right tool for the job is NOT perl but 'csplit'.
Re: Breaking large file into pieces
Author: Leslie Mikesell
Date: Wed, 12 Sep 1990 19:47
Date: Wed, 12 Sep 1990 19:47
28 lines
1262 bytes
1262 bytes
In article <1990Sep11.134238.20218@dg-rtp.dg.com> monroe@dg-rtp.dg.com (Mark A Monroe) writes: >I want to rip a large file into pieces, naming new files according >to an ID string in the large file. For example, the large file contains >records that look like this: >xxx-00001239 data data data >description > . > . >(variable length) > . > <---blank line >xxx-00001489 data data data The perl suggestions are the best if you have perl, and it can be done directly in awk if you have the new awk that can close files. I did this sort of thing years ago using: awk |sh where the awk program generates a stream something like: cat > filename1 <<\!EOF data !EOF cat > filename2 <<\!EOF data !EOF Les Mikesell les@chinet.chi.il.us
Re: Breaking large file into pieces
Author: Larry Wall
Date: Thu, 13 Sep 1990 00:54
Date: Thu, 13 Sep 1990 00:54
46 lines
2685 bytes
2685 bytes
In article <26116@boulder.Colorado.EDU> skwu@spot.Colorado.EDU.Colorado.EDU (WU SHI-KUEI) writes:
: The right tool for the job is NOT perl but 'csplit'.
"Those words fall too easily from your lips." --Gandalf
Let us attempt to distinguish fact from dogma.
1) As far as I can tell, csplit is AT&T proprietary. I certainly
don't have it on all my machines, and don't know offhand where
I'd find the source for it. The person we were advising may
well not have it on his machine. You should at least say "If
you have csplit..."
2) The man page for csplit (in the AT&T universe of a Pyramid, anyway)
indicates that you can have a maximum of 99 output files. The
application in question could easily have more than that, judging
by how it was specified. A general tool should not have
such limitations.
3) csplit won't name the files in the way specified--you'd have to
follow it up with a loopful of mv commands, one process per file.
And in the naive implementation, you'd have a sed or awk for each
file to extract out the filename to hand to mv.
4) csplit can't recognize patterns across newlines (not that this
job required that, but a general tool shouldn't have such
limitations.)
5) csplit can get confused on lines longer than 255 chars. It can't
handle embedded nulls. A general tool should not have such
limitations.
6) Even if I did manage to find a freely available source for csplit,
I'd have to worry about recompiling it on all my different
architectures. That would be okay (after all, I have to do that
with Perl too), but I have to do it for 50 blue jillion other little
"must have" tools too. I'd much rather compile Perl once on
each architecture, rewrite csplit in Perl, throw it into my
/u/scripts directory that's mounted everywhere, and never worry about
recompiling csplit again.
So it's not quite so simple as all that. You can chop down a tree with
a hatchet, but sometimes you want an industrial strength Swiss Army Chainsaw.
And sometimes not. There's more than one way to do it.
Larry
Re: Breaking large file into pieces
Author: Bob Peirce #305
Date: Thu, 13 Sep 1990 15:38
Date: Thu, 13 Sep 1990 15:38
14 lines
1167 bytes
1167 bytes
In article <9466@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: >In article <1990Sep11.134238.20218@dg-rtp.dg.com> monroe@dg-rtp.dg.com (Mark A Monroe) writes: >: I want to rip a large file into pieces, naming new files according >: to an ID string in the large file. For example, the large file contains >: records that look like this: >: >: Any suggestions? > >In standard shell+awk+sed it's a bit hard because you run out of file >descriptors. In nawk you can close the old file before you open the new. -- Bob Peirce, Pittsburgh, PA 412-471-5320 ...!uunet!pitt!investor!rbp rbp@investor.pgh.pa.us
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads