bash脚本提取员工名称
我最近参加了网络安全训练营,并且在用GREP命令编写此脚本时遇到了一些麻烦。我应该从时间表中提取员工姓名,脚本应该能够接受2个代表特定日期和特定时间的参数。 如果我在下面键入以下行,它将以0310的日期成功地进入时间表文件,并拔出凌晨5点工作的员工名称。
find -type f -iname *0310* | grep "05:00:00 AM" ./* | awk -F" " '{print $5, $6}'
但是,当我将其变成这样的脚本时:
#!/bin/bash
find -type f -iname *$1* | grep $2 ./* | awk -F" " '{print $3, $4}'
并执行这样的执行:
./script.sh 0310 "05:00:00 AM"
它为我提供以下错误代码,并打印在凌晨5点和下午5点工作的员工。
grep:am:没有这样的文件或目录
如果我在名称中有另一个带有“ 0310”的文件,我也会遇到此错误
查找:路径必须在表达式之前:
之后可能的无引用模式rando_file_with_0310.txt'find:predicate
-iname'?
这个脚本我在哪里出错?狂欢很新
I've recently enrolled in a cybersecurity bootcamp and am having a little trouble figuring out where I'm going wrong writing this script with a grep command. I'm supposed to be pulling employee names from a schedule and the script is supposed to be able to accept 2 arguments representing a specific date and a specific time.
If I type the following line below, it successfully goes into the schedule file with the date of 0310 and pulls the name of the employee that was working at 5am.
find -type f -iname *0310* | grep "05:00:00 AM" ./* | awk -F" " '{print $5, $6}'
However when I turn it into a script like this:
#!/bin/bash
find -type f -iname *$1* | grep $2 ./* | awk -F" " '{print $3, $4}'
And execute like this:
./script.sh 0310 "05:00:00 AM"
It gives me the following error code of the following and prints the employees who were working at 5am and also 5pm.
grep: AM: No such file or directory
I also get this error if I have another file with "0310" in the name
find: paths must precede expression:
random_file_with_0310.txt' find: possible unquoted pattern after predicate
-iname'?
Where am I going wrong with this script? Very new to BASH
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我 think 您实际想要的是:
请注意
awk
默认情况下,使用任意数量的whitespace(空格,选项卡)作为分隔符,因此您的字段分离器实际上可能不是您需要/想要什么。和一种不同的方法:
稍短(键入少),但涉及更多过程。
I think what you actually want is:
Note that
awk
by default uses any number of whitespace (spaces, tabs) as a separator, so your field-separator may not actually be what you need/want, either.And a different approach:
Slightly shorter (less typing), but more processes involved.
您的第一个问题是引用。
这是因为
GREP $ 2 ./* 正在运行
am
文件参数,然后扩展。 /*
是您从命令中运行的任何目录中的每个文件,这也不是您想要的。您在CLI示例中正确引用了它,但是您必须在脚本中引用它。这将正确传递“ 5:00:00 am”,但不会在
find
返回的文件中搜索它。假设只有一个文件(我不会,但是为了简单起见
)
... em>机会您将收到多个文件,然后这可能超出了训练营的范围,除非他们真的做对了,在这种情况下,CF 关于为什么不信任文件名的讨论。
无论如何 - 获得文件名后,您仍然不需要
grep
。甚至在一个步骤中,
...但是,如果您只是觉得需要添加一个冗余模式解析器,那么
可能的替代方案,而没有任何绩效的承诺...
请使用
此功能。您并将该列表传递给脚本。
awk
本身只会打开它作为参数传递的文件,因此您不再需要查找
。awk
也可以在这些文件中的行中进行模式匹配,因此您不再需要单独的grep
。(这确实有可能返回目录和其他怪异的可能性以及简单的文件;我们可以添加行以适应它,但是我试图为给定的问题保持相当简单。)
我省略了
- f“”
- 您可能不需要这一点,但是请务必测试它是否更改您的实际输出数据集。如果您的意思是您想要每个空间来界定字段,以便连续的空间表示空字段,请使用-f'[]'
。如果这对您的上下文来说太好了,那么Tink的答案可能就是您想要的。
You first problem is quoting.
This is because what
grep $2 ./*
is running ismaking
AM
the file argument, followed by the expansion of./*
which is every file in whatever directory you ran the command from, which is also not what you want. You quoted it correctly in your CLI example, but you have to quote it in your script.This will pass the "5:00:00 AM" correctly, but isn't going to search for it in the file(s) returned from
find
.Assuming there is only one file (I wouldn't, but for simplicity's sake...) - try
Personally, I prefer the improved syntax for the same thing -
If there is any chance you are going to get multiple files, then this is likely way beyond the scope of a bootcamp unless they are really doing it right, in which case c.f. this discussion of why filenames are not to be trusted.
ANYWAY - once you have your filename, you still don't need
grep
.or even, in one step,
...but if you just felt the need to add a redundant pattern parser antipattern, then
A possible alternative, with no promises on performance...
Call it with
This should let the interpreter locate matching files for you and pass that list to the script.
awk
itself will only open the files it is passed as arguments, so you no longer need thefind
.awk
can also pattern match for lines in those files, so you no longer need the separategrep
.(This does run the possibility of returning directories and other weirdness as well as just plain files; we can add lines to accommodate that, but I'm trying to keep it fairly simple for the given problem.)
I omitted the
-F" "
- you probably don't need that, but be sure to test to see if it changes your actual output dataset. If what you literally meant was that you want every space to delimit a field, so that consecutive spaces mean empty fields, use-F'[ ]'
.If that's too fancy for your context, tink's answer is probably what you want.