我目前正在做一些练习来尝试改进我的 shell 脚本。脚本的要求如下:
- 它必须使用命令获取用户名
whoami
并将其存储在名为 的变量中username
。- 它必须采用一个参数,即要搜索的文件的名称。
- 它必须
grep
在指定的文件中搜索用户名的出现并打印它们。
这部分相对简单,我使用了以下内容来使其工作:
username=$(whoami)
echo 'Enter the name of the file you would like to search: '
read fileName
cat "fileName" | grep "$username"
然而有一个问题,该练习指出以下内容:
笔记:对于此任务,无需担心缺少错误检查参数。除了 shebang 和您选择添加的任何注释之外,脚本应由两行组成。
我怎样才能将其减少到只有两行?
答案1
给出了文件的路径名作为参数。这意味着它是在脚本的命令行上给出的。这意味着您不应该以交互方式询问用户。
#!/bin/sh
grep -wF -e "$LOGNAME" "$1"
或者,如果您确实想使用whoami
:
#!/bin/sh
grep -wF -e "$(whoami)" "$1"
或者,对于“两条线”要求:
#!/bin/sh
name=$(whoami) # or: name=$LOGNAME
grep -wF -e "$name" "$1"
或者,如果我们想做某事有用在第一行:
#!/bin/sh
[ ! -f "$1" ] && { printf 'No such file: %s\n' "$1" >&2; exit 1; }
grep -wF -e "$(whoami)" "$1"
-w
使其grep
仅匹配完整单词的 选项。grep -w 'AA'
会匹配AA
但不匹配AAA
。
-F
使grep
实用程序将给定表达式作为固定字符串的选项,并且不是作为正则表达式。
该-e
选项表示命令行上的下一个字符串是模式。如果没有它,以破折号开头的模式可能会被错误地解释为一组命令行选项。
该变量$LOGNAME
(或$USER
在许多系统上)保存当前用户的用户名。
的值$1
是在命令行上赋予脚本的第一个命令行参数。
另请注意,我们可以使用 with/bin/sh
而不是 with执行此命令bash
,因为此脚本不使用特殊的bash
特定 shell 扩展。它显然会在bash
...下运行得很好。
注意上面的内容并没有搜索文件提及特定用户(如问题标题),而是搜索文件中的行提到了这个用户。
在某个文件中搜索提及当前用户的文件目录在命令行上给出:
#!/bin/sh
find "$1" -type f -exec grep -q -wF -e "$LOGNAME" {} ';' -print
与最后一部分相关:
- 了解“find”的 -exec 选项
man grep
在您的系统上。
答案2
最简单的解决方案:
#!/bin/bash
username=$(whoami)
grep $username $1
您可以为 grep 提供文件名作为可选参数(请参阅 参考资料man grep
)。该变量$1
指的是脚本的第一个位置参数。
您可以这样称呼它:
name-finder.sh filename
你甚至可以把它变成一行:
username=$(whoami); grep $username $1
或者
grep $(whoami) $1