本地与提供 Shell 脚本参数

Local vs Supplied Shell Script Arguments

编写接收 3 个参数的 shell 脚本,但在脚本中,其中一个命令需要在应用分隔符后检查第一个值

#!/bin/bash
awk -F'\t' ' ~ //&&// {print FS}' 

调用此命令:

bash search.sh 5 AM filename.txt

并且应该执行如下:

awk -F'\t' ' ~ /5/&&/AM/ {print FS}' filename.txt

该命令在 shell 脚本之外正常运行,returns 在 shell 脚本中使用它时现在什么也没有。 filename.txt :

03:00:00 AM John-James Hayward  Evalyn Howell   Chyna Mercado
04:00:00 AM Chyna Mercado   Cleveland Hanna Katey Bean
05:00:00 AM Katey Bean  Billy Jones Evalyn Howell
06:00:00 AM Evalyn Howell   Saima Mcdermott Cleveland Hanna
07:00:00 AM Cleveland Hanna Abigale Rich    Billy Jones

预期输出:

05:00:00 AM Billy Jones

当你用单引号引用时,你的论点没有被 shell 扩展。您可以使用 awk 变量(如@JohnKugelman 所建议的那样 ) 更清楚地分开 shell 和 awk 代码:

#!/bin/bash
awk -F'\t' -v p="" -v p2="" '([=10=] ~ p && [=10=] ~ p2) {print FS}' ""

我在这里使用通用变量名称(pp2)来强调您 不是 锚定您的正则表达式,因此它们确实匹配孔线而不是小时和 am/pm 按预期。

不要在 awk 脚本中嵌入 shell 变量。

这是一个带有一些解释性注释的解决方案:

#!/bin/bash

[[ $# -lt 2 ]] && exit 1       ## two args required, plus files or piped/redirected input

hour="$(printf '%02d' "")"   ## add a leading zero if neccesary
pm=${2^^}                      ## capitalise

shift 2

time="^$hour:.* $pm$"         ## match the whole time field

awk -F '\t' -v time="$time" \
' ~ time {print ,}' "$@" ## if it matches, print fields 1 and 3 (date, second name)

用法是 bash search.bash HOUR PM [FILE] ...,如果您使其可执行则为 ./search HOUR PM [FILE] ...。例如 ./search 5 am file.txt./search 05 AM file.txt.

我假设每个字段都由制表符分隔。

这可能是您想要做的(未经测试,使用任何 awk):

#!/usr/bin/env bash

awk -v hour="" -v ampm="" '
    BEGIN {
        FS = OFS = "\t"
        time = sprintf("%02d:00:00", hour)
    }
    ( == time) && ( == ampm) {
        print , 
    }
' "${3:--}"

请注意,即使您的输入文件包含 10:00:00 AM 并且使用的参数是 1 AM,以上内容仍然有效。考虑到其他一些解决方案会失败,因为它们使用的是部分正则表达式比较,因此 arg 1 将匹配 10:00:0011:00:00 输入中的 1s , 或 12:00:00.