我对脚本编写非常陌生,正在学习 Linux 终端课程。我们使用的是 Linux 发行版 Ubuntu。本周作业的一部分是,我们必须使用grep
和awk
来识别在分列的时间表文本文件中的特定时间在特定部门工作的员工。
使这一切变得困难的令人烦恼的部分是时间与时间是分开的,AM/PM
因此不可能轻松地 grep 时间,因为如果我放置05:00:00
它,它将同时显示工作人员AM
和行。PM
我找到了一个解决方案,只需输入:
grep -i ‘05:00:00 AM’ file.txt
这对我有用,并且给了我我需要的线路。
但问题是我需要在脚本中使用它并使用参数/变量,以便05:00:00 AM
我可以根据需要更改时间。然而,当我尝试放入‘$1’
我的脚本时
grep -i '$1' 0310_Dealer_schedule | awk -F " " '{print $5} {print $6}'
它从以红色突出显示的公认论点变为以黄色突出显示。
然后,当我尝试运行 时05:00:00 AM
,grep 将 视为AM
我正在查找的目录或文件。
接下来,我尝试$1
在脚本中不使用任何引号。然后当我去运行脚本时,我跑了
sh scriptname.sh ‘05:00:00 AM’
这也给了我错误“AM directory does not exist”
所以我想我想知道是否有成功的运行方法:
grep -i ‘05:00:00 AM’ file.txt | awk
-F “ “ ‘{print $5} {print $6}’
但其中 是05:00:00 AM
使其成为一个变量,您可以更改时间和AM
或PM
。
我不知道为什么带有引号或撇号的任何内容都会变成黄色。
我的脚本的目标是在我输入变量时生成值班经理的姓名。就像我说的,唯一困扰我的是尝试 grep05:00:00 AM
而不打印所有包含05:00:00
和 的行AM
。我希望它只是05:00:00 AM
连续打印该行。
这是我正在查找的文档的示例。希望结果是正确的。
TIME AM/PM TELLERS MANAGER
05:00:00 AM J. Doe C. Jones
06:00:00 AM J. Doe C. Jones
07:00:00 AM J. Doe C. Jones
08:00:00 AM J. Doe C. Jones
09:00:00 AM J. Doe C. Jones
10:00:00 AM J. Doe C. Jones
11:00:00 AM J. Doe C. Jones
12:00:00 PM A. Smith D. MILLER
01:00:00 PM A. Smith D. MILLER
02:00:00 PM A. Smith D. MILLER
03:00:00 PM A. Smith D. MILLER
04:00:00 PM A. Smith D. MILLER
05:00:00 PM A. Smith D. MILLER
感谢你们能带来的任何帮助。
编辑:文档在预览时可能不会分为几列。但在文档中它是用列分隔的
TIME AM/PM TELLERS MANGER
答案1
"
在变量周围添加双引号,例如"$1"
,这将允许 shell 扩展它,而 grep 仍会将其解释为单个参数
答案2
使用扩展正则表达式 (ERE) 保持简单:
在脚本中,输入时间作为第一个参数 ( $1
),输入上午或下午作为第二个参数 ( $2
)。因此,您可以将grep
指令写为:
grep -i -E "$1[[:blank:]]+$2" infile
- “infile”包含您要处理的内容。
-E
是扩展正则表达式标志[[:blank:]]
代表空格或制表符+
意味着 ERE 中之前出现的内容必须出现一次或多次。
但上面会打印整行。如果您只想将经理的姓名作为输出,请仅使用awk
notgrep
和awk
:
awk -v time=$1 -v suffix=$2 'BEGIN {pattern_ere=time"[[:blank:]]+"suffix} $0 ~ pattern_ere {print $5, $6}' infile
...假设awk
FS=OFS=" " 的默认值保持不变。
答案3
尝试使用下面的脚本,效果很好
#!/bin/bash
m=$1
q=$2
awk -v m="$m" -v q="$q" '$1 == m && $2 == q {print $5,$6}' file
输出
sh script.sh 05:00:00 AM
C. Jones
我有分配
变量 m 的第一个位置参数 变量 q 的第二个位置参数
最后一步使用此变量并比较文件中的column1和column2
答案4
首先,有几个因素需要考虑(我将myscript
在这些示例中简单地调用 shell 脚本,并假装它已被设置为简单地执行它myscript
而不是sh myscript
):
首先,考虑用户将如何执行命令:用户会键入myscript "05:00:00 AM"
、 or myscript 05:00:00 AM
、 甚至myscript 5:00 AM
吗?也就是说,他们会使用双引号来告诉命令行将整个事物视为一个参数,还是省略引号并将其视为两个参数?他们是否总是使用两位数字,并根据需要添加前导零?他们是否总是提供小时、分钟和秒(如果他们不指定上午/下午怎么办)?
每个问题都有解决方案,但为了简单起见,我将坚持要求他们始终必须键入myscript "hh:mm:ss xx"
,其中 hh、mm 和 ss 始终是两位数(以及有效时间,因此42
对于 'hh' 无效),'xx' 是 'am' 或 'pm'。另请注意,“AM/PM”可能是大写、小写,或者可能他们喝了太多啤酒并输入“aM”...)我将使大小写问题变得无关紧要,因为数字没有“外壳”,并且其他任何东西都可以简单地告诉 grep/awk/etc 在不区分大小写的模式下运行(使用 -i 标志,就像您已经完成的那样)。
使用上述先决条件,您给出的行grep -i '$1' 0310_Dealer_schedule | awk -F " " '{print $5} {print $6}'
是几乎正确的。 (编辑添加:这里的“正确”,我的意思是正如您所提供的那样——还有其他方法可以更有效地编码相同的内容。)想是grep -i "$1" 0310_Dealer_schedule | awk -F " " '{print $5} {print $6}'
。
请注意,区别在于您在不同地方使用的引号类型;无论是在命令行中还是在脚本中。
这是我为了测试而做的...
该脚本文件名为“myscript”(不带.sh扩展名,因为我使其直接可执行),并包含(注意不同部分使用的不同引号!):
#!/bin/env bash
grep -i "$1" data.txt | awk -F " " '{print $5} {print $6}'
我将您的数据放入名为“data.txt”的文件中。这是命令和输出:
$ ./myscript "05:00:00 AM"
C.
Jones
其效果如您所料。
因此,这里唯一真正的问题似乎是试图理解不同的引号如何影响不同的部分。
编辑还添加:另请注意 cbhihe 帖子中的信息,该信息重点关注awk
管道的侧面。我最初没有评论使用awk
(或其他任何内容),因为管道的那一侧取决于该grep
一侧的输出。