.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "TABLIFY 1p" .TH TABLIFY 1p "2015-04-21" "perl v5.20.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" tablify \- turn a delimited text file into a text table .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& tablify [options] file .Ve .PP Options: .PP .Vb 10 \& \-h|\-\-help Show help \& \-c|\-\-comment Define the beginning of a (single\-line) comment \& \-n|\-\-no\-headers Assume first line is data, not headers \& \-\-no\-pager Do not use $ENV{\*(AqPAGER\*(Aq} even if defined \& \-\-strip\-quotes Strip " or \*(Aq around fields \& \-l|\-\-list List the fields in the file (for use with \-f) \& \-f|\-\-fields=f1[,f2] Show only fields in comma\-separated list; \& when used in conjunction with "no\-headers" \& the list should be field numbers (starting at 1); \& otherwise, should be field names \& \-w|where=fv Apply the "cmp" Perl operator to restrict output \& where field "f" matches the value "v"; acceptable \& operators include ==, eq, >, >=, <=, and =~ \& \-v|\-\-vertical Show records vertically \& \-i|\-\-limit=n Limit to given number of records \& \-\-fs=x Use "x" as the field separator \& (default is tab "\et") \& \-\-rs=x Use "x" as the record separator \& (default is newline "\en") \& \-\-as\-html Create an HTML table instead of plain text \& \-\-headers Comma\-separated list of names matching \& the number of columns .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This script is essentially a quick way to parse a delimited text file and view it as a nice \s-1ASCII\s0 table. By selecting only certain \fBfields\fR, employing a \fBwhere\fR clause to only select records where a field matches some value, and using the \fBlimit\fR to only see some of the output, you almost have a mini-database front-end for a simple text file. .SH "EXAMPLES" .IX Header "EXAMPLES" Given a data file like this: .PP .Vb 6 \& name,rank,serial_no,is_living,age \& George,General,190293,0,64 \& Dwight,General,908348,0,75 \& Attila,Hun,,0,56 \& Tojo,Emporor,,0,87 \& Tommy,General,998110,1,54 .Ve .PP To find the fields you can reference, use the \fBlist\fR option: .PP .Vb 10 \& $ tablify \-\-fs \*(Aq,\*(Aq \-l people.dat \& +\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+ \& | Field No. | Field | \& +\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+ \& | 1 | name | \& | 2 | rank | \& | 3 | serial_no | \& | 4 | is_living | \& | 5 | age | \& +\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+ .Ve .PP To extract just the name and serial numbers, use the \fBfields\fR option: .PP .Vb 11 \& $ tablify \-\-fs \*(Aq,\*(Aq \-f name,serial_no people.dat \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+ \& | name | serial_no | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+ \& | George | 190293 | \& | Dwight | 908348 | \& | Attila | | \& | Tojo | | \& | Tommy | 998110 | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+ \& 5 records returned .Ve .PP To extract the first through third fields and the fifth field (where field numbers start at \*(L"1\*(R" \*(-- tip: use the \fBlist\fR option to quickly determine field numbers), use this syntax for \fBfields\fR: .PP .Vb 11 \& $ tablify \-\-fs \*(Aq,\*(Aq \-f 1\-3,5 people.dat \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | name | rank | serial_no | age | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | George | General | 190293 | 64 | \& | Dwight | General | 908348 | 75 | \& | Attila | Hun | | 56 | \& | Tojo | Emporor | | 87 | \& | Tommy | General | 998110 | 54 | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& 5 records returned .Ve .PP To select only the ones with six serial numbers, use a \fBwhere\fR clause: .PP .Vb 9 \& $ tablify \-\-fs \*(Aq,\*(Aq \-w \*(Aqserial_no=~/^\ed{6}$/\*(Aq people.dat \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | name | rank | serial_no | is_living | age | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | George | General | 190293 | 0 | 64 | \& | Dwight | General | 908348 | 0 | 75 | \& | Tommy | General | 998110 | 1 | 54 | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& 3 records returned .Ve .PP To find Dwight's record, you would do this: .PP .Vb 7 \& $ tablify \-\-fs \*(Aq,\*(Aq \-w \*(Aqname eq "Dwight"\*(Aq people.dat \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | name | rank | serial_no | is_living | age | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& | Dwight | General | 908348 | 0 | 75 | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-+ \& 1 record returned .Ve .PP To find the name of all the people with a serial number who are living: .PP .Vb 7 \& $ tablify \-\-fs \*(Aq,\*(Aq \-f name \-w \*(Aqis_living==1\*(Aq \-w \*(Aqserial_no>0\*(Aq people.dat \& +\-\-\-\-\-\-\-+ \& | name | \& +\-\-\-\-\-\-\-+ \& | Tommy | \& +\-\-\-\-\-\-\-+ \& 1 record returned .Ve .PP To filter outside of program and simply format the results, use \*(L"\-\*(R" as the last argument to force reading of \s-1STDIN \s0(and probably assume no headers): .PP .Vb 9 \& $ grep General people.dat | tablify \-\-fs \*(Aq,\*(Aq \-f 1\-3 \-\-no\-headers \- \& +\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& | Field1 | Field2 | Field3 | \& +\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& | General | 190293 | 0 | \& | General | 908348 | 0 | \& | General | 998110 | 1 | \& +\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& 3 records returned .Ve .PP When dealing with data lacking field names, you can specify \*(L"no-headers\*(R" and then refer to fields by number (starting at one), e.g.: .PP .Vb 9 \& $ tail \-5 people.dat | tablify \-\-fs \*(Aq,\*(Aq \-\-no\-headers \-w \*(Aq3 eq "General"\*(Aq \- \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& | Field1 | Field2 | Field3 | Field4 | Field5 | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& | George | General | 190293 | 0 | 64 | \& | Dwight | General | 908348 | 0 | 75 | \& | Tommy | General | 998110 | 1 | 54 | \& +\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& 3 records returned .Ve .PP If your file has many fields which are hard to see across the screen, consider using the vertical display with \*(L"\-v\*(R" or \*(L"\-\-vertical\*(R", e.g.: .PP .Vb 7 \& $ tablify \-\-fs \*(Aq,\*(Aq \-v \-\-limit 1 people.dat \& ************ Record 1 ************ \& name: George \& rank: General \& serial_no: 190293 \& is_living: 0 \& age : 64 \& \& 1 record returned .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 Text::RecordParser .IP "\(bu" 4 Text::TabularDisplay .IP "\(bu" 4 \&\s-1DBD::CSV\s0 .Sp Although I don't \s-1DBD::CSV\s0 this module, the idea was much the inspiration for this. I just didn't want to have to install \s-1DBI\s0 and \s-1DBD::CSV\s0 to get this kind of functionality. I think my interface is simpler. .SH "AUTHOR" .IX Header "AUTHOR" Ken Youens-Clark . .SH "LICENSE AND COPYRIGHT" .IX Header "LICENSE AND COPYRIGHT" Copyright (C) 2006\-10 Ken Youens-Clark. All rights reserved. .PP This program is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; version 2. .PP This program is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE. \s0 See the \s-1GNU\s0 General Public License for more details.