Path: utzoo!mnetor!uunet!husc6!cmcl2!rutgers!sunybcs!boulder!hao!noao!arizona!rupley
From: rupley@arizona.edu (John Rupley)
Newsgroups: comp.emacs
Subject: Re: transpose,rotate,mirror,reverse text...
Message-ID: <3167@megaron.arizona.edu>
Date: 11 Dec 87 19:00:11 GMT
References: <8129@steinmetz.steinmetz.UUCP> <1932@haddock.ISC.COM>
Organization: U of Arizona CS Dept, Tucson
Lines: 190
Summary: awk does it all, and easily




In article <1932@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>In article <8129@steinmetz.steinmetz.UUCP> nieh@moose.steinmetz (nico nieh) writes:
>>The following problems occurred to me yesterday while I was editing
>>a file which contains matrices.
>>
>>1. Is there an easy way to transpose a matrix in GNU-Emacs ?
>>2. Is there an easy way to rotate a rectangular of text +90/-90 degrees ?
>>3. Is there an easy way to mirror a rectangular of text (vertical/horizontal) ?
>>4. How about reverse a line or reverse a region ?
>>
>>Above questions should be applied to both character and word boundary.
>
>I have a program called "flip" that transposes an input stream by character.
		
>It probably wouldn't be too difficult to do with an awk script, either.
						     ^^^^^^^^^^

True, awk makes it easy to do all that the original poster wanted. The 
example below is for text, ie for (2), (3), and (4); (1), for numbers, 
is even easier.

Following is a quickie awk script to load an array, which you can 
read out however you want.  I run new awk, but I think all is 
compatible with the old awk. 

The script is for text lines of variable length.  Manipulating 
numerical arrays is simpler (that's how I prototyped, if one can 
speak of prototyping an awk script).  Change in the gsub /re/
allows change from character to word boundary or to number, and
this can be done dynamically, at least in the new awk, and
through command line settings.  Things could be prettied up and
function calls would simplify, but its late and I'm doing this
for fun.

Some test output is given at the end of the script.

*******NB: about 140 lines follow, so hit return if you're bored....

John Rupley
 uucp: ..{ihnp4 | hao!noao}!arizona!rupley!local
 internet: rupley!local@megaron.arizona.edu
 telex: 9103508679(JARJAR)
 (H) 30 Calle Belleza, Tucson AZ 85716 - (602) 325-4533
 (O) Dept. Biochemistry, Univ. Arizona, Tucson AZ 85721 - (602) 621-3929

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

awk '
BEGIN	{
		FS=":"
	}

	{
		#put in dummy separator, here a :
		gsub(/./, "&:")
		#split line into fields in array scr
		split($0, scr, ":")
		i = i + 1
		j = 1 + 0
		imax = i + 0
		jmax[i] = NF - 1
		if (jmax[i] > jmaxmax)
			jmaxmax = jmax[i]
		#fill doubly dimensioned array from elements of scr
		#i index = input row
		#j index = input field (no more than 10000)
		#the dummy index k is to make readout easier
		for (j = 1 + 0; j <= jmax[i]; j = j + 1)
		{
			k = i*10000 + j
			array[k] = scr[j]
		}
	}

#now that the input is stuffed into an array,
#read it out any-which-way
END	{	
		#add spaces to obtain rectangular matrix
		#you can get rid of trailing spaces later, if you want
		for (i = 1 + 0; i <= imax; i = i + 1)
		{
			for (j = 1 + jmax[i]; j <= jmaxmax; j = j + 1)
			{
				k = i*10000 + j
				array[k] = " "
			}
		}
		#output whatever (function calls would be nicer)
		print ""
		print "send out what came in"
		for (i = 1 + 0; i <= imax; i = i + 1)
		{
			outstr=""
			for (j = 1 + 0; j <= jmaxmax; j = j + 1)
			{
				k = i*10000 + j
				outstr = outstr  array[k]
			}
			print outstr
		}
		print ""
		print "reverse left-right"
		for (i = 1 + 0; i <= imax; i = i + 1)
		{
			outstr=""
			for (j = jmaxmax; j > 0; j = j - 1)
			{
				k = i*10000 + j
				outstr = outstr  array[k]
			}
			print outstr
		}
		print ""
		print "reverse top-bottom"
		for (i = imax + 0; i > 0; i = i - 1)
		{
			outstr=""
			for (j = 1 + 0; j <= jmaxmax; j = j + 1)
			{
				k = i*10000 + j
				outstr = outstr  array[k]
			}
			print outstr
		}
		print ""
		print "rotate + 90 degrees"
		for (j = 1 + 0; j <= jmaxmax; j = j + 1)
		{
			outstr=""
			for (i = imax + 0; i > 0; i = i - 1)
			{
				k = i*10000 + j
				outstr = outstr  array[k]
			}
			print outstr
		}
	}'
		
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

output for the following test block:

abcdefg
hijkl
mnopqrstu
v wx  yz
          0

is............

send out what came in
abcdefg    
hijkl      
mnopqrstu  
v wx  yz   
          0

reverse left-right (mirror vertically) (reverse region)
    gfedcba
      lkjih
  utsrqponm
   zy  xw v
0          

reverse top-bottom (mirror horizonatally)
          0
v wx  yz   
mnopqrstu  
hijkl      
abcdefg    

rotate + 90 degrees
 vmha
  nib
 wojc
 xpkd
  qle
  r f
 ys g
 zt  
  u  
     
0    

......and whatever else one's heart desires

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++