home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / perl / 5898 < prev    next >
Encoding:
Text File  |  1992-09-12  |  5.8 KB  |  182 lines

  1. Path: sparky!uunet!know!hri.com!snorkelwacker.mit.edu!paperboy.osf.org!meissner
  2. From: meissner@osf.org (Michael Meissner)
  3. Newsgroups: comp.lang.perl
  4. Subject: Re: Columnization
  5. Message-ID: <MEISSNER.92Sep13075954@curley.osf.org>
  6. Date: 13 Sep 92 11:59:58 GMT
  7. References: <1992Aug5.182712.14285@athena.mit.edu> <BtM68r.J0A@NCoast.ORG>
  8.     <1360@minya.UUCP>
  9. Sender: news@osf.org (USENET News System)
  10. Organization: Open Software Foundation
  11. Lines: 168
  12. In-Reply-To: jc@minya.UUCP's message of 11 Sep 92 18:27:19 GMT
  13.  
  14. In article <1360@minya.UUCP> jc@minya.UUCP (John Chambers) writes:
  15.  
  16. | > | Consider the example from the manual page:
  17. | > |    ls | paste - - - -
  18. | > | This is supposed to produce four-column output.  It does put the names
  19. | > | four  to a line, but in most directories, they will not be in columns.
  20. | > | There seems to be no options that will produce columnar output.
  21. | > 
  22. | > pr -m -t -w# file1 file2 ...
  23. | > 
  24. | > where # is the width (default 72).  May be System V only.
  25. | Several people have suggested something like this, but I don't see any
  26. | way  that  you can use pr to columnize the output of ls like the above
  27. | "ls | paste" command does (but correctly ;-). To do so, you would need
  28. | a  filter  that reads ls's output and writes it into N files, and then
  29. | feed these files to pr, and then remember to delete  the  intermediate
  30. | files.   If you're going to write this filter, well, you might just as
  31. | well have it write a single file (stdout) instead and align the fields
  32. | itself.  So pr doesn't help you at all. If you have to write a program
  33. | to chop up the data into multiple files, it's just as  easy  to  write
  34. | your own program in C or perl to do the entire job.
  35.  
  36. (I couldn't find the article the above article quotes, so hopefully it
  37. is solving the problem desired).
  38.  
  39. While it doesn't allow you to specify exactly 4 column output, my
  40. columnization library will automatically pick as many columns as can
  41. fit on the line size.  It would be used like:
  42.  
  43.     require 'columnize.pl'
  44.     chop (@lines = <STDIN>);
  45.     $, = '';
  46.     $\ = '';
  47.     print &columnize (4, 4, 72, 0, @lines);
  48.  
  49. The initial arguments to columnize are:
  50.  
  51.     Arg 1:    The number of leading spaces to print on each line.
  52.     Arg 2:    The number of spaces to leave between each column.
  53.     Arg 3:    The line width to use or 0, to use the current terminal's line size.
  54.     Arg 4:    The minimun column width to use
  55.     Arg 5-    Items to columnize.
  56.  
  57. Note the line_size has the system call number for TIOCGWINSZ hard
  58. coded.
  59.  
  60. #!/bin/sh
  61. # This is a shell archive (produced by shar 3.49)
  62. # To extract the files from this archive, save it to a file, remove
  63. # everything above the "!/bin/sh" line above, and type "sh file_name".
  64. #
  65. # made 09/13/1992 11:47 UTC by meissner@curley.osf.org
  66. # Source directory /usr/users/meissner/bin.perl
  67. #
  68. # existing files will NOT be overwritten unless -c is specified
  69. #
  70. # This shar contains:
  71. # length  mode       name
  72. # ------ ---------- ------------------------------------------
  73. #   2234 -rw-rw-r-- columnize.pl
  74. #
  75. # ============= columnize.pl ==============
  76. if test -f 'columnize.pl' -a X"$1" != X"-c"; then
  77.     echo 'x - skipping columnize.pl (File already exists)'
  78. else
  79. echo 'x - extracting columnize.pl (Text)'
  80. sed 's/^X//' << 'SHAR_EOF' > 'columnize.pl' &&
  81. X#! /usr/local/bin/perl
  82. X
  83. X# External function to return a string array, such that when each
  84. X# element is printed, it is printed as a series of columns, each
  85. X# equally spaced.
  86. X#
  87. X# Arg 1:    The number of leading spaces to print on each line.
  88. X# Arg 2:    The number of spaces to leave between each column.
  89. X# Arg 3:    The line width to use or 0, to use the current terminal's line size.
  90. X# Arg 4:    The minimun column width to use
  91. X# Arg 5-    Items to columnize.
  92. X
  93. Xsub columnize {
  94. X    package columnize;
  95. X    local ($leading_spaces)    = shift (@_);
  96. X    local ($num_spaces)    = shift (@_);
  97. X    local ($user_line_size)    = shift (@_);
  98. X    local ($max_length)    = shift (@_);
  99. X    local (@ret)        = ();
  100. X    local ($cur_col)    = 1;
  101. X    local ($initial)    = ("\t" x ($leading_spaces / 8)) . (' ' x ($leading_spaces % 8));
  102. X    local ($element);
  103. X    local ($ncols);
  104. X
  105. X    if ($#_ >= $[) {
  106. X        foreach $element (@_) {
  107. X            $max_length = length ($element)        if (length ($element) > $max_length);
  108. X        }
  109. X
  110. X        $ncols = &main'line_length ($user_line_size) - 1 - $leading_spaces;
  111. X        $ncols += ($num_spaces - 1)            if ($num_spaces > 0);
  112. X        $ncols /= ($max_length + $num_spaces);
  113. X        $ncols = 1                    if ($ncols <= 0);
  114. X
  115. X        foreach $element (@_[ $[ .. $#_ - 1 ]) {
  116. X            if (++$cur_col >= $ncols) {
  117. X                $cur_col = 1;
  118. X                push (@ret, "$initial$element\n");
  119. X                $initial = ' ' x $leading_spaces;
  120. X
  121. X            } else {
  122. X                push (@ret, ($initial . $element . (' ' x ($max_length - length ($element)))));
  123. X                $initial = ' ' x $num_spaces;
  124. X            }
  125. X        }
  126. X
  127. X        push (@ret, "$initial$_[$#_]\n");
  128. X    }
  129. X
  130. X    return @ret;
  131. X}
  132. X
  133. X
  134. X# Internal function to get the line length.
  135. X
  136. Xsub line_length {
  137. X    package columnize;
  138. X    local ($user_line_size)    = shift (@_);
  139. X
  140. X    return $user_line_size                if (defined ($user_line_size) && $user_line_size > 0);
  141. X
  142. X    if (! defined ($line_length) || ! $line_length) {
  143. X
  144. X        if (defined ($ENV{'COLUMNS'}) && $ENV{'COLUMNS'} > 0) {
  145. X            $line_length = $ENV{'COLUMNS'} + 0;
  146. X
  147. X        } else {
  148. X            local ($winsize)    = "\0\0\0\0\0\0\0\0";
  149. X            local ($TIOCGWINSZ)    = 0x40087468;        # on OSF/1 at least
  150. X            local (@winsize2);
  151. X
  152. X            $line_length = 79;
  153. X            if (-t STDIN && ioctl (STDIN, $TIOCGWINSZ, $winsize)) {
  154. X                @winsize2 = unpack ('SSSS', $winsize);
  155. X
  156. X                $line_length = $winsize2[1]    if ($winsize2[1] > 0);
  157. X            }
  158. X        }
  159. X    }
  160. X
  161. X    return $line_length;
  162. X}
  163. X
  164. X
  165. X# Return 1, so require succeeds.
  166. X
  167. X1;
  168. SHAR_EOF
  169. chmod 0664 columnize.pl ||
  170. echo 'restore of columnize.pl failed'
  171. Wc_c="`wc -c < 'columnize.pl'`"
  172. test 2234 -eq "$Wc_c" ||
  173.     echo 'columnize.pl: original size 2234, current size' "$Wc_c"
  174. fi
  175. exit 0
  176. --
  177. Michael Meissner    email: meissner@osf.org        phone: 617-621-8861
  178. Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142
  179.  
  180. You are in a twisty little passage of standards, all conflicting.
  181.