读取单词中的特定字符串时运行命令(例如开始新行)

读取单词中的特定字符串时运行命令(例如开始新行)

当脚本读取文本文件时,我希望此代码在特定变量中找到特定字符串时运行特定命令。

例子:

假设我想使用以下代码来读取命令的输出last

#!/bin/bash
for i in `last`; do 
  sleep 0.1 | echo -ne "$i " 
done

该命令的输出last是一个条目列表形式的表,类似于:

username  pts/2        1.2.3.4 via  Sun Sep  2 06:40 - 06:40  (00:00)
. . . . 
. . . . 
  1. i前面代码中的变量可以是上表中的任何短语。我想应用一个特定的命令,例如开始新行当代码在变量中找到特定字符串时i,例如当变量i包含闭括号时),我希望代码开始新行。

  2. 当代码完成读取命令的输出时last,我希望代码重复为了再次循环(多次)以读取是否有任何新的更新。如何指示代码再次重新运行?例如,是否有这样的命令goto可以强制代码转到特定行?

请您给点建议吗?

答案1

如果你的输出last是这样的:

username  pts/2        1.2.3.4 via  Sun Sep  2 06:40 - 06:40  (00:00)

并且您想在原来的位置添加换行符,那么我建议稍微改变一下逻辑。首先逐行读取输入,然后才将行拆分为单词。这样,就无需明确查找括号。您可以通过将其包装在 中来重复整个循环while true; do ... done。所以我们有这样的内容:

#!/bin/bash
set -f
while true; do
        last | while IFS= read -r line; do
                for word in $line; do
                        sleep .1
                        printf "%s " "$word"
                done
                echo     # prints a newline
        done
done

set -f禁用文件名扩展,否则可能会在未加引号的扩展中发生$line。另外,printf出于多种原因,我会使用echo 而不是 echo 来打印单词。

如果您确实想要查找右括号,那么您可以使用该[[ .. ]]测试:它允许与类似 glob 的模式或正则表达式进行模式匹配。 ([[ $word =~ $re ]]将是正则表达式匹配)

#!/bin/bash
set -f
while true; do
        for word in $(last); do
                sleep .1
                printf "%s " "$word"
                [[ $word = *')'* ]] && echo
        done
done

当然,尽管这一行不会在最终登录持续时间被替换为 之类的行上添加换行符still logged in

for word in $whatever结构的缺点是它对待多个空格就像对待单个空格一样,因此脚本的输出不会像原始那样将列整齐地对齐。

答案2

您可以使用if .. then类似以下的语句:

#!/bin/bash
for i in `last`; do 
    sleep 0.1 | echo -ne "$i " 
     if [[ $i = *')'* ]] ; then 
       echo "" ; 
     fi
done

如果您想for loop在 bash 中重复读取命令的输出(在您的示例中为 command last),那么您必须将脚本安排在crontab.更多澄清是这里

答案3

您可以采用不同的方法,我们需要您描述您的需求(识别特定人员的登录?识别谁在特定时间登录?等等)

正如您所说(当最后出现某些内容时添加换行符),您已经有了不同的方法:

#finding if a 'last' line contains a "specific_thing" (which is itself a regular expression...) 
# and can print all lines or not depending on showall value
while true ; do
  last | awk -v looking_for="specific_thing" -v showall=0 '
    ( showall == 1 )     { print $0 }
    ( $0 ~ looking_for ) { action="print line? and add something to it?" }
  '
done

#watch for new things appearing in last and not the whole "last" output every time
watch last | awk -v looking_for="specific_thing" -v showall=0 '
    ( showall == 1 )     { print $0 }
    ( $0 ~ looking_for ) { action="print the line? with added infos?"
                           action="execute : system(some command) ?"
                           action="all of that?" }
  '

ETC。

您还可以在日志文件中查找幽灵

您还可以在 /etc/profile 中插入一些命令(请注意,它可能会产生很多安全隐患,并且还可能在启动、初始化启动等时产生问题。这将是一个丑陋的黑客行为,可能会造成几个(或全部)用户的登录,无论如何都可以通过登录者快速按下 ctrl-C 来绕过...)

等等。有很多方法可以走,最好的方法就是修复你需要做的事情,现在必须坚持“最后”和“当我看到其中的内容时添加换行符”

为了获得更好的答案,请告诉我们您真正需要什么,以及您为什么需要它,而不是您认为您需要如何执行此或该操作(当您看到最后一个输出时添加换行符?您为什么认为您需要这样做的根本需求是什么?)

相关内容