本地与提供 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}' ""
我在这里使用通用变量名称(p
和 p2
)来强调您 不是 锚定您的正则表达式,因此它们确实匹配孔线而不是小时和 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:00
、11:00:00
输入中的 1
s , 或 12:00:00
.
编写接收 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}' ""
我在这里使用通用变量名称(p
和 p2
)来强调您 不是 锚定您的正则表达式,因此它们确实匹配孔线而不是小时和 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:00
、11:00:00
输入中的 1
s , 或 12:00:00
.