how to make several columns in a text file of different lengths the same length part2
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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.
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
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'.
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.
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.
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:
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"?
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!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.