我是 Unix 的新手。我自己学习......我正在编写一个简单的 shell 脚本来提取在指定时间轮班的经销商的姓名,其中从目录中的多个文件进行搜索。
想法是我需要能够传递文件日期(例如 0310)或文件中的时间(例如 05)或文件 AM 或 PM 中的时间类型,以拉出当时正在工作的特定经销商。
我可以使用以下脚本提取数据
grep -i '05' 0310* | awk -F " " '{print $(01) , $(02) , $(05) , $(06)}' | grep -i am > Dealers_working_during_losses.txt
这为我提供了上午 05 点文件名 0310_Dealer_Analysis 中列出的所有经销商的名称。现在我需要创建一个脚本,以便我可以提供日期、时间和时间类型作为参数,以便任何人都可以使用脚本。请告知如何进行?因为我是新蜜蜂,所以我会欣赏简单的解决方案,这样我就可以理解逻辑而不是复杂的东西......
以下是示例文件数据。我只需要提取轮盘赌庄家的数据。
Hour AM/PM BlackJack_Dealer_FNAME LAST Roulette_Dealer_FNAME LAST Texas_Hold_EM_dealer_FNAME LAST
12:00:00 AM Izabela Parrish Marlene Mcpherson Madina Britton
01:00:00 AM Billy Jones Saima Mcdermott Summer-Louise Hammond
02:00:00 AM Summer-Louise Hammond Abigale Rich John-James Hayward
03:00:00 AM John-James Hayward Evalyn Howell Chyna Mercado
答案1
首先让我们清理现有的脚本:
1) -i
grep 的 arg 用于小写字母比较,因此在数字上使用它没有意义。所以只需摆脱-i
from即可grep -i '05' 0310*
。
2)" "
是 awk 的默认 FS 值,因此您不需要指定它-F " "
- 只需将其也删除即可。
3) 输入字段编号不需要是 2 位数字,也不需要用括号括起来来分隔它们,因此每个$(01)
等都可以是$1
等。
4)当你使用 awk 时,你永远不需要 grep,所以:
grep '05' 0310* |
awk '{print $1, $2, $5, $6}' |
grep -i am > Dealers_working_during_losses.txt
可以写成:
awk '/05/{$0=$1 OFS $2 OFS $5 OFS $6; if (tolower($0) ~ /am/) print}' 0310* > Dealers_working_during_losses.txt
现在让我们修复现有的错误:
5)/05/
会发现05
任何地方在记录中(例如作为分钟字段),但您只想在记录的开头找到它,因为那是小时规范所在的位置,因此将其更改为/^05/
.
6)类似地,就像grep -i am
做的那样,tolower($0) ~ /am/
将am
在记录中的任何位置(例如在人名中)找到它,但您只想在它是记录中的第二个字段时找到它,因此将其更改为tolower($2) == "am"
我们现在有这个命令:
awk '/^05/{$0=$1 OFS $2 OFS $5 OFS $6; if (tolower($2) == "am") print}' 0310* > Dealers_working_during_losses.txt
但由于我们只测试$2
am 或 pm,因此我们不需要在测试然后打印之前先构建一个全新的记录 ($0),而是可以这样做:
awk '/^05/{if (tolower($2) == "am") print $1, $2, $5, $6}' 0310* > Dealers_working_during_losses.txt
我们可以更惯用地写为:
awk '/^05/ && (tolower($2) == "am") {print $1, $2, $5, $6}' 0310* > Dealers_working_during_losses.txt
现在介绍如何创建一个接受所有值参数的 shell 脚本。那是:
#!/usr/bin/env bash
awk -v time="$2" -v ampm="$3" '($0 ~ ("^"time)) && (tolower($2) == tolower(ampm)) {print $1, $2, $5, $6}' "$1"* > Dealers_working_during_losses.txt
假设上面的内容存储foo
在您的 中名为 的可执行文件中PATH
,您可以这样调用:
foo 0310 05 am
我认为上面唯一不明显的是,当我们从测试文字值 ( ^05
) 到通过连接字符串"^"
与变量值生成的字符串时,我们必须使用不同的语法进行时间比较time
,因为使用正则表达式上下文中的字符串要求我们使用动态正则表达式/.../
这也意味着不能使用常量正则表达式比较中的快捷方式$0 ~ /.../
,因此我们也需要编写该$0 ~
部分。