LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-27-2009, 02:13 PM   #1
Mike_V
Member
 
Registered: Apr 2009
Location: Boston MA
Distribution: CentOS 6.2 x86_64 GNU/Linux
Posts: 59

Rep: Reputation: 19
how to make several columns in a text file of different lengths the same length PART2


Hi there,

I posted a question similar to this before:
http://www.linuxquestions.org/questi...7/#post3518614

I thought I would be able to get my answer from the replies from that previous post but I'm not...


Here it is:

I have a matrix of numbers separated by a space in a text file that looks like this:

Code:
2 3 9 8 9 6 
6 9 0 8 5 
4 9 8 7 
6 5 4
1 3
5
(FYI: I don't have a 6x6 matrix, as the example above, but 400x400)

Now I want to fill the total matrix with zero's in the lower triangle, such that the lower rows are filled with zero's starting on the left (so the lower rows will scoot up as many places as there are zero's introduced.

Code:
2 3 9 8 9 6 
0 6 9 0 8 5
0 0 4 9 8 7
0 0 0 6 5 4
0 0 0 0 1 3
0 0 0 0 0 5
Thanks for your help!

Last edited by Mike_V; 04-27-2009 at 02:23 PM.
 
Old 04-27-2009, 03:28 PM   #2
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
Here is the start of a solution. (This version strikes me as inefficient because it gets the count of digits in each line twice.)

Edit: On the subway home, I thought of a better solution, so this no longer applies. The script now only counts the digits for each line once (using tr/// which strikes me as a reasonably quick way to do this without actually changing the lines. If someone has a better solution, I'll be glad to hear it.) Even if it isn't perfect, it should give you something to start from.

Code:
#!/usr/bin/env perl
use strict;
use warnings;

open my $fh, '<', 'matrix' or die "Can't open file for reading: $!";

# Work through the file once to figure out the longest line
my $longest_line = 0;
my @lengths;
my $line = 0;
while (<$fh>) {
  $lengths[$line] = tr/' '//;
  if ($lengths[$line] > $longest_line) {
    $longest_line = $lengths[$line];
  }
  $line++;
}

# Rewind to the start of the file
# Reset the line count variable to 0
seek $fh, 0, 0;
$line = 0;

# Now work back through the file and do the real work
# Add the '0' plus a space the right number of times by
# subtracting the difference in count between the longest
# line and the current line
while (<$fh>) {
  my $difference = $longest_line - $lengths[$line];
  if ($difference) {
    $_ = '0 ' x $difference . $_;
  }
  print $_;
  $line++;
}
This works on the data you gave, and it produces nicely lined-up output. However, if your numbers vary in how many digits they have, then the output won't be so pretty (unless you do extra work to format the output).

Last edited by Telemachos; 04-27-2009 at 06:48 PM.
 
Old 04-27-2009, 08:55 PM   #3
Mike_V
Member
 
Registered: Apr 2009
Location: Boston MA
Distribution: CentOS 6.2 x86_64 GNU/Linux
Posts: 59

Original Poster
Rep: Reputation: 19
Hi Telemachos,
your script did EXACTLY what I hoped it would do (and what you said it would do ;-)).
I appreciate you sharing your experience and time a lot!
M.
 
Old 04-27-2009, 10:29 PM   #4
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Here's a Python one
Code:
data=[i.strip() for i in open("matrix").readlines() ]
# get max length
maxnum = max([ len(i.split())  for i in data])
for line in data:
    while len(line.split()) < maxnum:  line = '0 ' + line;
    print line
output:
Code:
# ./test.py
2 3 9 8 9 6
0 6 9 0 8 5
0 0 4 9 8 7
0 0 0 6 5 4
0 0 0 0 1 3
0 0 0 0 0 5
 
Old 04-27-2009, 11:04 PM   #5
Mike_V
Member
 
Registered: Apr 2009
Location: Boston MA
Distribution: CentOS 6.2 x86_64 GNU/Linux
Posts: 59

Original Poster
Rep: Reputation: 19
Hi ghostdog74,
I do like the simplicity of yours. And indeed it works great on my testfile and also one my 400 x 400 matrix.
I cannot thank you guys enough.

============

Some tips in case someone (else) who does not have a lot of experience might try to use the scripts above:

The text/script for the perl version above from Telemachos must be put into a text file that has this line as first line:
#!/usr/bin/env perl
and the file should be saved with the extension: .cgi


The text/script for the python version above from ghostdog74 must be put into a text file that has this line as first line:
#!/usr/bin/env python
and the file should be saved with the extension: .py

In both version replace the word 'matrix' with 'name_of_file_containing_the_matrix'.

Cheers,
 
Old 04-28-2009, 02:42 AM   #6
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,348

Rep: Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749
Actually, perl filenames usually have .pl extensions. Sometimes(!) you might find .cgi in web apps, but its not reqd. Just depends on the setting in httpd.conf.
 
Old 04-28-2009, 08:52 AM   #7
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
I tend not to add .pl or .rb to my programs. If you make the file executable and give it a correct shebang line (the first one, the #! line), it's not strictly necessary. And I figure that it's nobody's business whether it's a Perl script or a Ruby one or a Python one. I assume that this would also work for Python scripts, but I don't use it, so I won't swear to that.
 
Old 04-28-2009, 06:23 PM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Well, if we are talking just about upper triangular matrix to square one conversion, then the suggested pieces of code are algorithmic overkill, and simple stupid solution is:

Code:
     1  #!/usr/bin/perl -w
     2
     3  use strict;
     4
     5  my $leading_zeros = '';
     6
     7  while(defined(my $line = <STDIN>))
     8    {
     9    print $leading_zeros, $line;
    10    $leading_zeros .= '0 ';
    11    }
,

and here's how it works:

Code:
sergei@amdam2:~/junk> cat -n input_matrix.txt
     1  2 3 9 8 9 6
     2  6 9 0 8 5
     3  4 9 8 7
     4  6 5 4
     5  1 3
     6  5
sergei@amdam2:~/junk> ./triangular_to_square.pl < input_matrix.txt
2 3 9 8 9 6
0 6 9 0 8 5
0 0 4 9 8 7
0 0 0 6 5 4
0 0 0 0 1 3
0 0 0 0 0 5
sergei@amdam2:~/junk>
 
Old 04-29-2009, 08:32 AM   #9
Mike_V
Member
 
Registered: Apr 2009
Location: Boston MA
Distribution: CentOS 6.2 x86_64 GNU/Linux
Posts: 59

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by Telemachos View Post
I tend not to add .pl or .rb to my programs. If you make the file executable and give it a correct shebang line (the first one, the #! line), it's not strictly necessary. And I figure that it's nobody's business whether it's a Perl script or a Ruby one or a Python one. I assume that this would also work for Python scripts, but I don't use it, so I won't swear to that.
OK, but I'm a newbie. What shebang would you suggest for your perl script? And how do I "make the file executable"?

And to Sergei Steshenko: thanks for the addition!

Last edited by Mike_V; 04-29-2009 at 08:35 AM.
 
Old 04-29-2009, 09:25 AM   #10
radoulov
Member
 
Registered: Apr 2007
Location: Milano, Italia/Варна, България
Distribution: Ubuntu, Open SUSE
Posts: 212

Rep: Reputation: 38
With awk(use gawk, nawk or /usr/xpg4/bin/awk on Solaris):

Code:
awk 'NR==1{m=NF}NF<m{p=x;for(i=1;i<=m-NF;i++)
p=p?p FS 0:x 0;$1=p FS$1}1' infile

Last edited by radoulov; 04-29-2009 at 09:29 AM.
 
Old 05-15-2009, 12:55 AM   #11
Mike_V
Member
 
Registered: Apr 2009
Location: Boston MA
Distribution: CentOS 6.2 x86_64 GNU/Linux
Posts: 59

Original Poster
Rep: Reputation: 19
radoulov: Thanks for the last addition, I'm going to try it out...

UPDATE 5-22-09
radoulov: Your awk one-liner works perfect and I can incorporate that line very nicely in my larger c shell script without going to perl or python. But... also knowing those perl and python options is very useful. So: thanks to all!

Last edited by Mike_V; 05-22-2009 at 10:46 AM.
 
Old 05-15-2009, 01:44 AM   #12
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,348

Rep: Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749Reputation: 2749
The shebang line is just the first line that tells the system what lang to use eg

#!/usr/bin/perl -w

adjust to wherever your Perl (or bash or python...) are located.

You make it executable using chmod

chmod u+x program.pl
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how to make several columns in a text file of different lengths the same length Mike_V Programming 3 04-23-2009 09:17 PM
bash/sed/awk fill each line in text file with space to fixed length khairil Programming 11 01-09-2008 05:28 AM
sed: delete text till <pattern2> depending on length of text oyarsamoh Programming 2 05-05-2007 01:40 AM
delete columns 15 to 27 of a text file powah Programming 1 01-31-2007 02:03 AM
storing text in a text file for a specified length of time. mrobertson Programming 7 08-02-2005 10:27 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:10 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration