stu@gtisqr.uucp (Stu Donaldson) (11/20/90)
I need a detab function written in perl. I'm sure there must be something other than the brute force method of implimenting this. Any help would be appreciated... How about a one liner? :-) -- Stu -- Stu Donaldson UUCP: {smart-host}!gtisqr!stu Maverick Microsystems ARPA: gtisqr!stu@beaver.cs.washington.edu Mukilteo, Washington Bell: (206) 743-6659
merlyn@iwarp.intel.com (Randal Schwartz) (11/21/90)
In article <1990Nov19.210123.20558@gtisqr.uucp>, stu@gtisqr (Stu Donaldson) writes: | I need a detab function written in perl. I'm sure there must be | something other than the brute force method of implimenting this. | | Any help would be appreciated... | | How about a one liner? :-) Like maybe: perl -pe '1 while s/\t/" " x (8-length($`)%8)/e' This is not the same as: perl -pe 's/\t/" " x (8-length($`)%8)/eg' # wrong! Although I didn't test it, I recall something about length($`) being wrong in a global edit, so I skipped that version. The first one works, however. print "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: "Intel: putting the 'backward' in 'backward compatible'..."====/
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/21/90)
In article <1990Nov19.210123.20558@gtisqr.uucp> stu@gtisqr.uucp (Stu Donaldson) writes: : I need a detab function written in perl. I'm sure there must be : something other than the brute force method of implimenting this. : : Any help would be appreciated... : : How about a one liner? :-) Depends on what you mean by "detab". If you mean get rid of leading tabs: s/^(\t+)/' ' x (length($1) * 8)/e; If you mean get rid of all tabs like expand(1) does, then do this: 0 while s/\t/' ' x (8 - length($`) % 8)/e; If you mean to reduce the indentation of your lines, here's a program called retab: #!/usr/bin/perl 'di'; 'ig00'; # # $Header: retab,v 1.1 90/08/12 00:21:20 lwall Locked $ # # $Log: retab,v $ # Revision 1.1 90/08/12 00:21:20 lwall # Initial revision # $sw = 4; $sw = $1, shift if $ARGV[0] =~ /^-(\d+)/; while (<>) { s#^( +)#"\t" x (length($1) / 8) . " " x (length($1) % 8)#e; s#^(\t*)( *)#' ' x ($sw * length($1)) . ' ' x (length($2) * $sw / 8)#e; s#^( +)#"\t" x (length($1) / 8) . " " x (length($1) % 8)#e; print; } ############################################################################## # These next few lines are legal in both Perl and nroff. .00; # finish .ig 'di \" finish diversion--previous line must be blank .nr nl 0-1 \" fake up transition to first page again .nr % 0 \" start at page 1 '; __END__ ############# From here on it's a standard manual page ############ .TH RETAB 1 "August 11, 1990" .AT 3 .SH NAME retab \- change indentation from every 8 columns to fewer columns .SH SYNOPSIS .B retab [-<tabwidth>] [files] .SH DESCRIPTION .I Retab reads its input and shrinks all the initial whitespace down by some factor. By default it changes 8 spaces (one hardware tab) to 4 spaces, but you can give a switch to change it to any number of spaces. .PP Processing happens in three stages on each line. First all initial tabs are converted to the equivalent number of spaces. Then the number of spaces are reduced by the specified amount. Then leading spaces are converted back to tabs 8 spaces at a time. .SH ENVIRONMENT No environment variables are used. .SH FILES None. .SH AUTHOR Larry Wall .SH BUGS It might not pick exactly the same spacing you might pick for half-indented lines when converting from, say, 8 to 3 columns per indent. Larry (No, I'm not one of the bugs...)
niklas@appli.se (Niklas Hallqvist) (11/21/90)
stu@gtisqr.uucp (Stu Donaldson) writes: >I need a detab function written in perl. I'm sure there must be >something other than the brute force method of implimenting this. >Any help would be appreciated... > How about a one liner? :-) Well, Here's my try: perl -pe 's/^([^\t]*)\t/$1." "x(8-length($1)%8)/e while /\t/;' Now, this is a bad one, since I loop once for each tab on a line. I thought this one would take care of that problem, but NO, it did NOT! perl -pe 's/^([^\t]*)\t/$1." "x(8-length($1)%8)/eg;' Shouldn't the g flag work with the e flag, doing just what I did explicitly in my first try? Now, don't worry... I'm sure Randal & Larry will replace this script with a thirty-byter... ;^) Niklas -- Niklas Hallqvist Phone: +46-(0)31-40 75 00 Applitron Datasystem Fax: +46-(0)31-83 39 50 Molndalsvagen 95 Email: niklas@appli.se S-412 63 GOTEBORG, Sweden mcsun!sunic!chalmers!appli!niklas
utashiro@sran84.sra.co.jp (Kazumasa Utashiro) (11/21/90)
In article <1990Nov20.175000.1407@iwarp.intel.com> merlyn@iwarp.intel.com (Randal Schwartz) writes: >> | I need a detab function written in perl. I'm sure there must be >> | something other than the brute force method of implimenting this. >> >> Like maybe: >> >> perl -pe '1 while s/\t/" " x (8-length($`)%8)/e' To handle control character correctly, I'm doing like this: 1 while s/\t/" " x (8-&width($`)%8)/e; sub width { local($_)=shift; return(length($_)) unless (/[\033\010\f\r]/); s/^.*[\f\r]//; s/\033\$[\@B]|\033\([JB]//g; # this is for Japanese code 1 while s/[^\010]\010//; s/^\010*//; length($_); } Is there any better way? --- K. Utashiro utashiro@sra.co.jp
inc@tc.fluke.COM (Gary Benson) (11/21/90)
In article <1990Nov19.210123.20558@gtisqr.uucp> stu@gtisqr.uucp (Stu Donaldson) writes: >I need a detab function written in perl. I'm sure there must be >something other than the brute force method of implimenting this. > >Any help would be appreciated... > > How about a one liner? :-) > Well it's not a one-liner, and I didn't even write it -- credit Craig Johnson here at Fluke for it: while (/\t/) { $x = index($_, "\t"); $n = 8 - ($x & 7); $spaces = (" " x $n); s/\t/$spaces/; This relies on the unix 8-spaces-per-tab convention. Depending on your exact circumstances, you may need to change the expression in the assignment of $n. For a while, I thought that our emacs had been set up to create and expect 5-space tabs, so Craig changed the third line for me to read: $n = 5 - ($x % 5); -- Gary Benson -=[ S M I L E R ]=- -_-_-_-inc@fluke.com_-_-_-_-_-_-_-_-_-_- If we make peaceful revolution impossible, we make violent revolution inevitable. -John F. Kennedy