在bash脚本中执行我的第一步。到目前为止,我已经完成了5/7的练习,陷入了最后两个阶段,我无法找到解决这个问题的方法。
下面是对请求的练习的更好的转换,应该使用sed、echo、cat、uniq、tr、grep、wc等简单命令来解决相同的问题:
编写命令行,该命令行显示默认shell是计算机上可用shell之一的用户数量。在执行命令时,对于每个shell,我们将得到如下相同形式的结果:
f 211
@托德
今天早上我做了,你的grep重定向输入给了我这个想法。我就是这样做的:
result=$(grep -of <(echo $SHELL) /etc/passwd | uniq -c)count=$(echo $result I awk -F” “ '{print $1}')shell=$(echo $result | awk -F” “'{print $2}')echo $result | while read i; doecho $count utilisateurs ont pour shell $shelldone发布于 2021-10-14 10:56:39
Unix实用程序和Bash过程替换
在巴斯,有很多方法可以做到这一点。然而,从实际的角度来看,您并不需要Bash本身来解决这个问题。标准*nix工具会做得很好,只要您正确地将它们连接起来。例如,如果输出的特定格式不是要点:
$ grep -of <(grep '^/.*$' /etc/shells) /etc/passwd | sort | uniq -c
11 /bin/bash
8 /bin/sh
4 /usr/local/bin/fish这基本上是从/etc/shell中获取shell,然后grep将该输出作为一个文件来读取表达式,以便与/etc/passwd匹配。然后,它将结果传送到sort和uniq实用程序,以计数出现的情况。它依赖于进程替换,而进程替换并不是所有shell都有相同的方式或表示方式,但是您的问题是用Bash标记的,所以避免使用Bashism并不是一个主要问题。
然而,由于并非所有shell都具有Bash所做的进程替换重定向,因此这样的解决方案并不是跨不同shell 100%可移植的。通常有类似的方法,但有时跨系统和shell的可移植性非常重要。无论如何,这表明grep、管道和进程替换是多么强大。
一旦您有了原始数据,您就可以使用printf、awk甚至sed格式化输出,如果您想要使用不同的格式。但是,如果重点是计算shell的使用情况,在Bash或zsh中这样做是一种简单的方法。
更便携的选择
一个更复杂(但也更易于移植)的选择是使用xargs作为管道的核心元素。例如:
$ grep -o '^/.*$' /etc/shells |
xargs -I{} -L1 -- sh -c 'echo "{}"; grep -Fc "{}" /etc/passwd' |
xargs -n2
/bin/bash 11
/bin/csh 0
/bin/ksh 0
/bin/sh 8
/bin/tcsh 0
/bin/zsh 0
/usr/local/bin/fish 4这将找到/etc/shell中的所有shell,将它们一次一个地传递给Bourne脚本,以打印shell的路径,并让grep的固定字符串匹配器计数/etc/passwd中出现的情况,然后再将输出输送到xargs,每次将行连接回两个。
这种方法的主要好处是它将列出所有shell,无论是否有人使用它们。如果希望在shell名称之前列出数字,甚至可以将最后一行更改为tac | xargs -n2。
发布于 2021-10-14 04:05:24
这就是我如何理解你的问题,一种使用数组的方法,包括关联数组。
#!/usr/bin/env bash
declare -A Shell_and_Users
while IFS=: read -ra lines; do
login_shell="${lines[-1]}"
((Shell_and_Users["$login_shell"]++))
done < /etc/passwd要检查关联数组Shell_and_Users的值,请运行:
declare -p Shell_and_Users现在循环遍历关联数组以打印所需的输出。
for i in "${!Shell_and_Users[@]}"; do
printf -- '- %d users have shell %s\n' "${Shell_and_Users[$i]}" "$i"
done如果不是这样,那么编辑问题并添加更多细节,如果文件/etc/shells应该解析/涉及,因为上面的解决方案永远不会打印0 users。
发布于 2021-10-14 05:44:08
假设可以使用awk,您可以尝试以下方法
$ cat awk.script
#!/usr/bin/env awk -f
BEGIN {
FS=":"
} $NF=="/bin/bash" {
count_bash++
bash=$NF
} $NF=="/usr/bin/bash" {
count_bash2++
bash2=$NF
} $NF=="/bin/sh" {
count_sh++
sh=$NF
} $NF=="/usr/bin/sh" {
count_sh2++
sh2=$NF
} END {
print count_bash " users have a shell for "bash "\n" \
count_bash2" users have a shell for "bash2 "\n" \
count_sh " users have a shell for "sh "\n" \
count_sh2" users have a shell for "sh2 "\n" \
}这将提供与预期输出类似的输出,但是,如果shell没有使用,您将得到一个没有值或路径的空输出,这可能并不理想。
输出
$ awk -f awk.script /etc/passwd
24 users have a shell for /bin/bash
users have a shell for
2 users have a shell for /bin/sh
users have a shell forhttps://stackoverflow.com/questions/69564539
复制相似问题