将参数传递给 ARGV[1] [duplicate]

passing an argument to ARGV[1] [duplicate]

提问人:ZyPH3R 提问时间:11/17/2023 最后编辑:Charles DuffyZyPH3R 更新时间:11/17/2023 访问量:41

问:

我们每天都会生成日志文件,其名称如下

log.$AUTOSERVE.mmddyyyy

日志文件包含如下数据:

[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: FAILURE         JOB: ABC MACHINE: 111.test.com
[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: TERMINATED      JOB: XYZ MACHINE: 222.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: STARTING        JOB: 123 MACHINE: 333.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: 456 MACHINE: 444.test.com 
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: ABC123 MACHINE: 555.test.com
[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: FAILURE         JOB: ABC MACHINE: 111.test.com
[11/16/2023 07:13:45]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: TERMINATED      JOB: XYZ MACHINE: 222.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: STARTING        JOB: 123 MACHINE: 333.test.com
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: 456 MACHINE: 444.test.com 
[11/16/2023 07:13:46]      CAUAJM_I_40245 EVENT: CHANGE_STATUS    STATUS: SUCCESS         JOB: ABC123 MACHINE: 555.test.com

我有一个 shell 脚本,用于过滤此文件中的 MACHINE 和 STATUS 搜索字符串,并计算每台机器上运行了多少个作业,这是我的代码:log

#!/bin/bash
dt=$(date -d "yesterday" '+%m%d%Y')
cat /tmp/log.$AUTOSERVE.dt \
  | perl -ne '/STATUS:\s+(\w+).+MACHINE:\s+(\w+.\w+.\w+)$/ && print join( "\t", $1, $2 ). "\n"' \
  | grep -E '(SUCCESS|FAILURE|TERMINATED)' \
  | cut -f2 \
  | sort \
  | uniq -c \
  | perl -ne '/^\s+(\d+)\s+(.*)$/ && print join("\t", '$ARGV[1]', $ENV{AUTOSERV}, $2, $1) . "\n"' $date_YYYYMMDD \
  > /tmp/output.txt

我得到的输出是:

ARRAY(0x5569464a3630)   NP2     111.test.com      2
ARRAY(0x5569464a3678)   NP2     222.test.com      2
ARRAY(0x5569464a3648)   NP2     444.test.com      2
ARRAY(0x5569464a3630)   NP2     555.test.com      2

我尝试将$date_YYYYMMDD$dt:

cat /tmp/log.$AUTOSERVE.dt \
  | perl -ne '/STATUS:\s+(\w+).+MACHINE:\s+(\w+.\w+.\w+)$/ && print join( "\t", $1, $2 ). "\n"' \
  | grep -E '(SUCCESS|FAILURE|TERMINATED)' \
  | cut -f2 \
  | sort \
  | uniq -c \
  | perl -ne '/^\s+(\d+)\s+(.*)$/ && print join("\t", '$ARGV[1]', $ENV{AUTOSERV}, $2, $1) . "\n"' $dt \
  > /tmp/output.txt

但是我收到以下错误:

Can't open 11152023: No such file or directory.

我期望的输出是:

11152023   NP2     111.test.com      2
11152023   NP2     222.test.com      2
11152023   NP2     444.test.com      2
11152023   NP2     555.test.com      2

我做错了什么

Bash 外壳 Unix

评论

0赞 Charles Duffy 11/17/2023
当您想确定某些内容扩展到多少个 argv 元素时,请使用引号。不。foo "$arg"foo $arg
1赞 Charles Duffy 11/17/2023
考虑通过 shellcheck.net 运行代码,这样可以捕获该问题和其他问题。
0赞 Charles Duffy 11/17/2023
顺便说一句,Stack Overflow 支持块引号——你不需要单独编码行格式。
0赞 Charles Duffy 11/17/2023
...虽然我想知道你是否过于严格地遵循了 linter 的建议:你的 perl 代码中有单引号,但这会使 shell 而不是 perl 扩展,因为它们结束了你拥有其余 perl 代码的单引号上下文。不要那样做:你可能希望没有任何单引号。$ARGV[1]$ARGVprint join("\t", $ARGV[1], $ENV{AUTOSERV}
2赞 Charles Duffy 11/17/2023
(以这种方式在 Perl 和 shell 之间来回跳转通常也是次优的;你通常可以在 Perl 中完成所有逻辑,而不需要来回管道;awk 通常也是如此)。

答: 暂无答案