如何使用Perl或awk重新格式化GECOS字段?

时间:2010-02-03 17:11:40

标签: perl awk

我想扫描passwd文件并将评论字段中的字词顺序从名字姓氏更改为姓氏名字,并强制使用姓氏大写字母。

因此,改变以下各行:

jbloggs:x:9999:99:Joe Bloggs:/home/jbloggs:/bin/ksh

为:

jbloggs:x:9999:99:BLOGGS Joe:/home/jbloggs:/bin/ksh

我是Perl的新手,我遇到了awk中不同字段分隔符的问题。 感谢任何帮助。

6 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

独立示例:

use strict;
use warnings;
my $s = 'jbloggs:x:9999:99:Joe Bloggs:/home/jbloggs:/bin/ksh';
my @tokens = split /:/, $s;
my ($first, $last) = split /\s+/, $tokens[4];
$tokens[4] = uc($last) . " $first";
print join(':', @tokens), "\n";

__END__
jbloggs:x:9999:99:BLOGGS Joe:/home/jbloggs:/bin/ksh

作为脚本(输出到STDOUT;必须将输出重定向到文件):

use strict;
use warnings;
while (<>) {
    chomp;
    my @tokens = split /:/;
    my ($first, $last) = split /\s+/, $tokens[4];
    $tokens[4] = uc($last) . " $first";
    print join(':', @tokens), "\n";
}

答案 2 :(得分:1)

$ awk -F":" ' { split($5,a," ");$5=toupper(a[2])" "a[1] } 1 ' OFS=":" /etc/passwd
jbloggs:x:9999:99:BLOGGS Joe:/home/jbloggs:/bin/ksh

答案 3 :(得分:1)

$ awk -v FS=":" '{split($5, a, " "); name = toupper(a[2]) " " a[1]; gsub($5, name); print $0}' passwd

如果你有中间名,那将无效。

编辑:更易于阅读的版本

awk -v FS=":" '
{
    split($5, name_parts, " ")
    name = toupper(name_parts[2]) " " name_parts[1]
    gsub($5, name)
    print $0
}' passwd

答案 4 :(得分:1)

这将在您读取文件时处理该文件,并将新格式条目放入数组@newEntries中。

open PASSWD, "/etc/passwd";
while(<PASSWD>) {
    @fields = split /:/;
    ($first, $last) = split (/\s/, $fields[4]);
    $last = uc $last;
    $fields[4] = "$last $first";
    push @newEntries, join(':', @fields);
}

答案 5 :(得分:1)

$ perl -pe 's/^((.*:){4})(\S+)\s+(\S+?):/$1\U$4\E, $3:/' \
    /etc/passwd >/tmp/newpasswd

要仅重写根据lastlog在过去60天内登录的用户,您可以使用

#! /usr/bin/perl -n

use warnings;
use strict;

use Date::Parse;

my($user) = /^([^:]+):/;
die "$0: $ARGV:$.: no user\n" unless defined $user;

if ($user eq "+") {
  next;
}

my $lastlog = (split " ", `lastlog -u "$user" | sed 1d`, 4)[-1];
die "$0: $ARGV:$.: lastlog -u $user failed\n"
  unless defined $lastlog;

my $time_t = str2time $lastlog;

# rewrites users who've never logged in
#next if defined $time_t && $time_t < ($^T - 60 * 24 * 60 * 60);

# users who have logged in within the last sixty days
next unless defined $time_t && $time_t >= ($^T - 60 * 24 * 60 * 60);

s/^((.*:){4})(\S+)\s+(\S+?):/$1\U$4\E, $3:/;
print;

,如

$ ./fixusers /etc/passwd >/tmp/fixedusers