Misbehaving sort function

  • Thread starter Vahid Moghaddasi
  • Start date
V

Vahid Moghaddasi

Hi,
I have been trying to sort -u the password file /etc/passwd by its
first field (username) but for some reason sort is giving me a wrong
result. This is what I used:
"sort -t : -k 1,1 /etc/passwd" I do not use -u to see the result of the

sort command.
In the passwd file, I have the first 5 lines copied to the buttom of
the file (duplicate system accounts, root,daemon,bin,sys,adm with
different uid,gid's ) I have the users in the middle.
When I sort -u, I would like to see either the top 5 system users or
the bottom ones but I see one from top, one from the bottom and so on.
There is no pattern to the output, it seems that -k 1,1 does not have
any effect at all.
I would appreciate if someone shed a light on this or paste a function
to do the sort for me.
I need to sort by username and in another function by UID.
Thanks,
Vahid.
 
P

Paul Lalli

Vahid said:
I have been trying to sort -u the password file /etc/passwd by its
first field (username) but for some reason sort is giving me a wrong
result. This is what I used:
"sort -t : -k 1,1 /etc/passwd" I do not use -u to see the result of the

sort command.
In the passwd file, I have the first 5 lines copied to the buttom of
the file (duplicate system accounts, root,daemon,bin,sys,adm with
different uid,gid's ) I have the users in the middle.
When I sort -u, I would like to see either the top 5 system users or
the bottom ones but I see one from top, one from the bottom and so on.
There is no pattern to the output, it seems that -k 1,1 does not have
any effect at all.
I would appreciate if someone shed a light on this or paste a function
to do the sort for me.
I need to sort by username and in another function by UID.

It sounds an awful lot like you're confusing the Unix command 'sort'
with the Perl function 'sort'. While they have the same name, they
have nothing else in common.

If you're looking for a Perl solution to your problem, you should start
by making an attempt at a Perl solution, and then posting your attempt
here if it doesn't work.

Paul Lalli
 
V

Vahid Moghaddasi

Paul said:
It sounds an awful lot like you're confusing the Unix command 'sort'
with the Perl function 'sort'. While they have the same name, they
have nothing else in common.

If you're looking for a Perl solution to your problem, you should start
by making an attempt at a Perl solution, and then posting your attempt
here if it doesn't work.
I am looking for a perl solution which gives me a similar result as
sort -t: -k1,1 in unix.
Unix sort command does not guarantee order of the sort as I mentioned
in my posting.
 
X

xhoster

Vahid Moghaddasi said:
I am looking for a perl solution which gives me a similar result as
sort -t: -k1,1 in unix.

It seems like you are looking for a Perl solution that does what you think
"sort -t: -k1,1" should do, rather than what it actually does do. But
your description of what you think it should do is not clear, so how
can we help you?
Unix sort command does not guarantee order of the sort as I mentioned
in my posting.

The sort command doesn't sort? Wow! But that wasn't what I got out of
your first post. It sounded like it sorted properly, but that the behavior
of the -u switch was the thing that didn't do what you wanted. Now it is
the sort itself?

Maybe you are looking for this:

awk -F: '{print $1}' | sort -u


Xho
 
P

Paul Lalli

Vahid said:
I am looking for a perl solution which gives me a similar result as
sort -t: -k1,1 in unix.
Unix sort command does not guarantee order of the sort as I mentioned
in my posting.

Okay. So my advice remains the same. What have you tried so far (in
Perl)? How did it go wrong? What part do you need help with?

A few helpful pointers might be:
perldoc -f open
perldoc -f readline
perldoc -f sort
perldoc -f print

Paul Lalli
 
V

Vahid Moghaddasi

Paul said:
Okay. So my advice remains the same. What have you tried so far (in
Perl)? How did it go wrong? What part do you need help with?

A few helpful pointers might be:
perldoc -f open
perldoc -f readline
perldoc -f sort
perldoc -f print
Paul,
Here is what I did in perl but it is a system call so it not really a
perl sort function, I would like to change this to a native perl sort
if possible.
system(" cat passwd | awk -F: '{printf "%s-%04d %s:%s:%s:%s:%s:%s:% \
s\n",$1,NR,$1,$2,$3,$4,$5,$6,$7}' | sort -k1,1 | sed -e 's/-/ /' | \
sort -k1,1 -u | sort -k2,2 | cut -d " " -f3-");

I need to remove the duplicate username from the password file if they
appear again while parsing the file. For example if root is at the top
of the file, any second username 'root' should be discarded.
Thanks,
 
P

Paul Lalli

Vahid said:
Paul,
Here is what I did in perl but it is a system call so it not really a
perl sort function, I would like to change this to a native perl sort
if possible.
system(" cat passwd | awk -F: '{printf "%s-%04d %s:%s:%s:%s:%s:%s:% \
s\n",$1,NR,$1,$2,$3,$4,$5,$6,$7}' | sort -k1,1 | sed -e 's/-/ /' | \
sort -k1,1 -u | sort -k2,2 | cut -d " " -f3-");

I need to remove the duplicate username from the password file if they
appear again while parsing the file. For example if root is at the top
of the file, any second username 'root' should be discarded.

I'm seriously starting to feel like I'm talking to a brick wall.
You're right, that's *not* a Perl solution. No one here is likely to
write a Perl solution for you. What we *will* do is HELP you with your
own Perl solution. So go make an attempt at solving your problem with
Perl, then come back here if that solution doesn't work, and we can
help you figure out why.

This is the third and final time I give you this advice. Go make an
attempt. Then ask us for help with the results of that attempt if
needed.

Paul Lalli
 
J

John W. Krahn

Vahid said:
Paul,
Here is what I did in perl but it is a system call so it not really a
perl sort function, I would like to change this to a native perl sort
if possible.
system(" cat passwd | awk -F: '{printf "%s-%04d %s:%s:%s:%s:%s:%s:% \
s\n",$1,NR,$1,$2,$3,$4,$5,$6,$7}' | sort -k1,1 | sed -e 's/-/ /' | \
sort -k1,1 -u | sort -k2,2 | cut -d " " -f3-");

I need to remove the duplicate username from the password file if they
appear again while parsing the file. For example if root is at the top
of the file, any second username 'root' should be discarded.

Modified from code provided by Randal L. Schwartz:
http://groups-beta.google.com/group/perl.beginners/msg/51a3e9ab2644cd42?hl=en&

#!/usr/bin/perl
use warnings;
use strict;

unless ( @ARGV ) {
# no argument passed, so call ourselves inside vipw:
$ENV{ EDITOR } = $0; # vipw will call us now instead of vi/emacs/whatever
exec 'vipw';
die "Cannot exec vipw: $!";
}

# argument passed means that vipw has called us with a temp filename

# edit it inplace
$^I = '~';
# and all at once (for reasons that are hard to explain here)
$/ = undef;

my %seen;

my @lines = split /\n/, <>; # only one read gets the entire file
# anything we print replaces that entire file
print map "$_\n",
map join( ':', @$_ ),
# sort { $a->[ 2 ] <=> $b->[ 2 ] } # sort by UID
sort { $a->[ 0 ] cmp $b->[ 0 ] } # sort by user name
grep !seen{ $_->[ 0 ] }++,
map [ split /:/ ],
@lines;

__END__


John
 
V

Vahid Moghaddasi

John W. Krahn wrote:

Thank you John, the link and program was really helpful.
 
V

Vahid Moghaddasi

Jim said:
Here is a short program that might be enough to get you started:
El perfecto!
You program is just what I need to add to my over 400 lines of perl
codes. I am not a seasoned perl programmer and trying not use many
system() calls.
Thank you very much Jim for the perfect pointer.
Vahid.
 
V

Vahid Moghaddasi

Jim said:
That sounds possibly dangerous or at least confusing. If you try to log
in as one of these accounts, how is the system supposed to which entry
to use. On my system, user names are unique.
You are correct, the end result of my program will have unique username
and UID in the password file.
That is two different problems. In my system, I always see the first
entry. This is known as a "stable" sort. The order of identical entries
is preserved. It sounds like you are using an unstable sort algorithm.
Check the man pages for sort and look at the -s option.
I did not see -s in the man page on Solaris 9,10, HP-UX11i, AIX 5.2,3
did not check Linux but in any case, the -s must exist on all unix
platform where my program runs.
-k 1,1 does not appear to have any effect because the default sort uses
the entire line. Therefore it sorts first by the first field, so the
output result is the same. Try "-k 2,2" or "-k 3,3" to see that the -k
is actually working. Also compare the results with "-k 1,1" and then
with "-u -k 1,1" and then with just "-u" to see the effect of -k and -u
together.
I am using -k 3,3n and seem to be working fine, I guess -k 1,1 has a
problem on Solaris, HP and AIX, it looks OK on Linux. I wrote a sort
program in C but I would rather user a built-in perl function so I
don't have to keep adding programs to 4000+ unix machines.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,948
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top