【问题标题】:AWK. Filtering by pattern from variable with spacesAWK。按模式从带空格的变量中过滤
【发布时间】:2021-10-16 12:20:23
【问题描述】:

A 有问题。我有这样的东西:(命令最后的输出)

user123  pts/18       workstation Fri Aug 13 07:34   still logged in
user123  pts/12       workstation Fri Aug 13 07:34   still logged in
user123  pts/11       workstation Fri Aug 12 07:34   still logged in
user123  pts/10       workstation Fri Aug 12 07:34   still logged in
user123  pts/7        workstation Fri Aug 11 07:34   still logged in
user123  pts/5        workstation Fri Aug 11 07:34   still logged in

我想按今天的日期过滤

v_data=`date +%c | awk '{print $1,$2,$3}'`

下一个

last | head -n 30 | grep user123 | grep $v_data

我得到错误

grep: Aug: No such file or directory
grep: 13: No such file or directory

我试着 awk

last | head -n 30 | grep user123 | awk -v v1=$v_data '/v1/'

还是什么都没有

我能做什么?

【问题讨论】:

  • last | head -n 30 | grep user123 没有给出任何输出,因此 grep 和 awk 没有要处理的数据。

标签: parsing awk grep


【解决方案1】:

首先使用date获得与last输出完全相同的格式:

$ date +'%a %b %d'
Fri Aug 13

还有grep

last | head -n 30 | grep "user123.*$(date +'%a %b %d')"

正如 Ed 所注意到的,这也可以匹配包含 user123 的用户名行,例如 user1234。如果发生这种情况,我们必须使用更具体的正则表达式:

last | head -n 30 | grep "^user123 .*$(date +'%a %b %d')"

^ 匹配行首)。

当然,如果您在last 输出的前30 行中没有匹配的行,那么您看不到任何内容是绝对正常的。所以首先检查你是否有这样的行:

user123 <something> Fri Aug 13 <something>

last的未过滤输出中。

【讨论】:

  • 完全正确。我尽可能多地重用了 OP 的原始解决方案,但实际上它可能会失败。我采纳了你的建议。
【解决方案2】:

如果您将命令 last | head -n 30 | grep user123 | grep $v_data 复制/粘贴到 http://shellcheck.next 中,它会告诉您它有什么问题。

仅打印包含您的日期的行是:

$ grep "$(date +'%a %b %d')" file
user123  pts/18       workstation Fri Aug 13 07:34   still logged in
user123  pts/12       workstation Fri Aug 13 07:34   still logged in

但要从管道输入的前 30 行(即last 的输出)中稳健地打印特定用户+日期组合的行是:

$ last | awk -v d="$(date +'%a %b %d')" -v u='user123' '($1==u) && (($4" "$5" "$6)==d){print} NR==30{exit}'
user123  pts/18       workstation Fri Aug 13 07:34   still logged in
user123  pts/12       workstation Fri Aug 13 07:34   still logged in

【讨论】:

    【解决方案3】:

    使用 GNU awk 作为一个完整的解决方案:

    awk '$1=="user123" && NR <=30 { if (match($0,strftime("%a %b %d",systime()))) { print } }' <(last)
    

    将 last 的输出重定向回 awk。如果第一个空格分隔字段等于“user123”,请检查是否包含格式为例如的当前日期的行“Fri Aug 13” 如果是,则打印该行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 2021-10-18
      • 2018-11-02
      • 2015-06-19
      • 1970-01-01
      相关资源
      最近更新 更多