如何为不同的shell获取一行中所有用户的上次登录时间

时间:2013-04-15 19:25:54

标签: shell unix sh ksh csh

我可以使以下行在ksh上工作

for user in $( awk -F: '{ print $1}' /etc/passwd); do last $user | head -1 ; done | tr -s "\n" |sort

但是我想让它在UNIX sh和UNIX csh上运行。 (在Linux中它运行正常,但linux不是unix ...)

我知道这有一些限制,因为似乎每个UNIX(*)在语法上都有自己的变体。

更新:对不起,这里有一些限制:

  1. 我无法写入磁盘,因此无法保存脚本。
  2. 我如何在CSH中写这个?

4 个答案:

答案 0 :(得分:3)

这个awk-script似乎等同于你在上面循环:

{
  cmd = "last "$1
  cmd | getline result
  printf "%s",  result
}

像这样使用它:

awk -F: -f script_above.awk /etc/passwd

将输出管道传输到sort

作为一个单行:

$ awk -F: '{cmd = "last "$1; cmd | getline result;printf "%s", result}' /etc/passwd

答案 1 :(得分:2)

这可能对你有用,应该符合POSIX:

last | awk 'FNR==NR{split($0,f,/:/);a[f[1]];next}($1 in a)&&++b[$1]==1' /etc/passwd - |  sort

答案 2 :(得分:0)

你真的不需要Awk。

while IFS=: read user _; do
    last "$user" | head -n 1
done </etc/passwd  # | grep .

而不是在Csh中重新发明它,怎么样

sh -c 'while IFS=: read user _; do last "$user" | head -n 1; done </etc/passwd'

wtmp轮换后未登录的用户将获得空输出;也许可以添加| grep .来清除那些。 (我在上面注释了它。)

重申一下,IFS=:将shell的内部字段分隔符设置为冒号,以便read将密码文件分开。

答案 3 :(得分:0)

只需使用简单的命令:

select t.*, left(names, charindex(';', names + ';') - 1) as first_name
from (values 
    (1, 'John;Betty;Dave;Bob'), 
    (2, 'Mary;Raul;Felix'), 
    (3, 'foo')
) t(id, names)