🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.utils.bug
Article #194

csplit

#194
From: Francois Pinard
Date: Sun, 02 Aug 1992 19:13
126 lines
5508 bytes
I'm playing with GNU csplit from textutils 1.3.  Here are some
thoughts!  Let me first ask for some clarifications in the man page.

* The man page suggests that:

	/pattern/+N

create a file up to, but excluding the line having /pattern/ in it;
then the +N indicate which line will start the next section.  But
testing shows that when +N is used, the line containing /pattern/ is
not excluded from the previous file.  In fact, no line is excluded at
all, and /pattern/+N merely advances where the cut is done.

* Experimentation shows that, once all patterns has been obeyed, the
remaining of the input file is written as one supplementary output
file.  Is that correct?  If yes, the man page should be made more
clear about it.  Also, the man page speaks about the possibility of
creating zero output file.  How currently is this easily achievable?


Now, let me submit a few suggestions, after which would follow
examples and justification.

* The empty patterns // and %% should match the current line without
advancing.  Right now, experimentation did not show an always
predictable behaviour.

* There should be a syntax in patterns or repeat counts meaning an
infinite number `without error', that is, the highest finite number
which would not imply an error.  Just to throw an idea in, let me
suppose that the empty string, used whenever a number is expected, has
precisely this meaning.

* There should be a way to group patterns before applying repeat
counts to them, so a repeat count could mean a certain number of
cycling through the pattern list.  Ideally, group should be nested
many times; but even if only one level of nesting was possible, this
would still be quite useful.  I noticed that csplit is careful to
avoid shell special characters in its syntax, I'll do the same and
suggest using isolated `{' and `}' for grouping.


Ok, let's proceed with some examples.  They are inspired from a small
program I already wrote, which outputs one `xxNN' file per page from a
given input file, for all pages in it.  I think csplit should be able
to replace and fairly extend my program.  (In the incoming examples,
`^l' always mean a single character, which is the form feed).


* I found no easy way in csplit to avoid writing the remaining of the
file.  Given the previous suggestions, one could write:

	csplit -s input /^l/ {10} %%+

meaning that we first extract eleven pages on eleven different pages,
then match the empty string on the current line, extend this match an
infinite number of lines forward, that is, until the end of the file,
and then avoid writing any output for this match.


*  Using csplit as it is, I can split all pages from a file with:

	csplit -ks input /^l/ {1000}

The `-k' is required because without it, the number 1000 being too
great, this causes an error, so all output files are removed.  To
avoid all stastic output, I also use `-s'.  However, I always receive:

	csplit `/^l/': match not found on repetition NN

With the given suggestions, I could write instead:

	csplit -s input /^l/ {}

which is more elegant at least for two reasons: I do not have to use
an arbitrarily large number, the empty number meaning infinite; and
the program does not produce any diagnostic.


* For splitting up a Babyl file, one could use:

	csplit -s RMAIL %^l% { %EOOH%+1 /^l/ } {}

The first pattern would remove the Babyl header.  Then, an infinite
repeat would apply to the two remaining patterns, because the repeat
immediately follow a parenthesized group and so, applying to it.  So,
in alternance, the Babyl internal header would be skipped until EOOH,
then the following line up to a form feed line (excluded) would be
output on a separate file.


* A way to split a file into its pages without retaining the form
feeds in the produced files could be:

	csplit -s input { /^l/ %%+1 } {}

The null pattern matches the current line, the applied adjustment has
the purpose of skipping it.


Let me add two final remarks about the LINE pattern, which means to
skip to some absolute line number, while producing an output file.

* There is no current way to ask for skipping to an absolute line
number *without* producing an output file.

* The specification that a repeat count applied to an absolute line
produces more files having all this number of lines seems really
meaningful to me only if the LINE pattern is really the first on the
command line.  The actual writing:

	csplit -s input 700 {5}

is really a short form for:

	csplit -s input 700 //+700 {5}

the first 700 is absolute, the other relative.  I do not really see
the point of using a repeat construct for the LINE pattern elsewhere.
Maybe the short form should be disallowed as meaningless whenever the
LINE pattern is not the first on the command line.

-- 
Franc,ois Pinard        ``Vivement GNU!''        pinard@iro.umontreal.ca
(514) 588-4656                                    ...!uunet!iros1!pinard
Consider joining the League for Programming Freedom.  Email for details!
Technical Details
Message-ID: <9208021913.AA15763@icule.UUCP>
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!icule.UUCP!pinard

Show Full Headers
Complete Article Headers
Newsgroups: gnu.utils.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!icule.UUCP!pinard
From: pinard@icule.UUCP (Francois Pinard)
Subject: csplit
Message-ID: <9208021913.AA15763@icule.UUCP>
Sender: gnulists@ai.mit.edu
Reply-To: pinard@iro.umontreal.ca
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sun, 2 Aug 1992 19:13:29 GMT
Approved: bug-gnu-utils@prep.ai.mit.edu
Lines: 127