Linux 使用grep和cut筛选who的输出
我有一个练习: 创建一个bash脚本,检查作为参数传递的用户是否正确 已连接,并且在连接时显示是否已连接。指示:使用who命令、grep筛选器和 命令切断 但我有一些麻烦来解决它Linux 使用grep和cut筛选who的输出,linux,bash,Linux,Bash,我有一个练习: 创建一个bash脚本,检查作为参数传递的用户是否正确 已连接,并且在连接时显示是否已连接。指示:使用who命令、grep筛选器和 命令切断 但我有一些麻烦来解决它 #!/bin/bash who>who.txt; then grep $1 who.txt for a in who.txt do echo "$a" done else echo "$1 isnt connected" fi 首先,我只想保留一行,我可以
#!/bin/bash
who>who.txt;
then
grep $1 who.txt
for a in who.txt
do
echo "$a"
done
else
echo "$1 isnt connected"
fi
首先,我只想保留一行,我可以在.txt中找到用户,然后我想在who命令中用一个循环剪切每个部分,只保留日期,但问题是我不知道如何在这里剪切,因为它用多个空格分隔
所以我真的被堵住了,我不知道该怎么做。我是bash的初学者。如果我知道您只是想检查用户是否登录,那么这就是
users
命令的作用。如果要将其包装成一个简短的脚本,则可以执行以下操作:
#!/bin/bash
[ -z "$1" ] && { ## validate 1 argument given on command line
printf "error: insufficient input, usage: %s username.\n" "${0##*/}" >&2
exit 1
}
## check if that argument is among the logged in users
if $(users | grep -q "$1" >/dev/null 2>&1) ; then
printf " user: %s is logged in.\n" "$1"
else
printf " user: %s is NOT logged in.\n" "$1"
fi
示例/使用
$ bash chkuser.sh dog
user: dog is NOT logged in.
$ bash chkuser.sh david
user: david is logged in.
cut
对于解析who
的输出是一个相当笨拙的工具,除非您使用固定的列位置。在分隔符模式下,使用-d'
,每个空格将生成一个单独的空字段。它不像awk
那样,字段由一行空格分隔
who(1)
输出如下(GNUwho
没有选项将其缩减为用户名/时间):
我没有检查很长的用户名会发生什么,不管它们是否被截断,或者它们是否将行的其余部分移到另一行。使用awk'{print$3,$4}
解析它会感觉更安全,因为不管列的确切位置如何,它仍然可以工作
但由于您需要使用cut
,因此我们假设这些精确的列位置(从23开始到38的时间)在我们希望该脚本工作的所有系统以及所有终端宽度中都是恒定的。(who
对于$COLUMNS
或tty驱动程序列宽(stty-a
输出中的COLUMNS
字段),似乎不会改变其输出)
综上所述:
#!/bin/sh
who | grep "^$1 " | cut -c 23-38
grep命令行上的正则表达式将只在行首匹配,并且必须匹配用户名后面的空格(以避免子字符串匹配)。然后通过cut
过滤匹配的行,以仅提取包含时间戳的列
如果cmdline arg为空,则将打印每个登录用户的登录时间。如果模式与任何内容都不匹配,则输出将为空。要显式地检测并打印其他内容,请使用var=$(pipeline)
捕获管道输出,并测试它是否为空字符串
这将为来自同一用户的每个单独登录打印时间。您可以使用grep的count limit arg(参见手册页)在一场比赛后停止,但这可能不是最近的一次。您可以使用sort-n | head-1
或其他方法
如果您不必在shell中编写循环,就不要这样做。最好编写一个管道,让一个人通过数据。shell本身速度很慢,但只要它不必解析您正在处理的每一行内容,这并不重要 还要注意我是如何用双引号引用
$1
的扩展的,以避免shell对其应用分词和全局扩展
有关更多shell内容,请参阅。这是一个很好的入门学习习惯用法的地方(即,当您的文件名和目录中有空格,或文件名包含
?
,或带有尾随空格的行,您不想咀嚼…)时,不要中断。脚本的开头是否应该有if
?显示who
的输出示例会很有用。您可能需要查看“管道”功能,以便将一个命令的输出直接发送到另一个命令。例如,您可以将who
的输出导入grep
,将grep
的输出导入cut
,所有这些都在一条管道中。请注意,who.txt中的对于who.txt的不会循环到who.txt
的内容上。循环运行一次,使用a=who.txt
。有关如何解析文件,请参阅Bash常见问题解答(在我的答案中链接)。你可以用who |而IFS=read…
,在纯bash中(除了who
),而不是使用grep
和cut
来解决整个问题,如果你真的想这样做的话。将grep
管道放在命令替换中,而不仅仅是if-who | grep-q。。。;那么
?您不希望管道打印任何未重定向到/dev/null的输出,因为它将作为命令运行,而不是显示为脚本输出。可能更有用的是将输出捕获到变量中,以便他可以使用cut
对其进行过滤,以获得登录时间。同意。将用户的结果
放入数组等。。始终是一个选项,但不知道提问者的专业水平,我不愿意用额外的语法使解决方案过于复杂,等等--另外,这个问题现在和我回答的时候大不一样了。哦,在发帖后的前5分钟里,OP做了一些编辑吗?修订列表仅为原始->我的重新引用。我花了一段时间才找到实际想要的输出,但它就在他引用的家庭作业中。如果我没记错的话,最初的问题基本上只是我回答它时的第一句话。
#!/bin/sh
who | grep "^$1 " | cut -c 23-38