所以我真的被困在这里了。我得到了一些包含数百万行数据的文件,格式如下:
username|process name|process time (in minutes)
这些数据有将近 340 万行。现在我手头的任务是编写一个脚本,以便快速浏览所有这些数据。
所以基本上我想从命令行输入一个用户名,提取该用户名的所有数据行,将它们相加,然后显示。含义例如该用户的总处理时间以及该用户的进程总数。
这是我到目前为止所拥有的,而且不多
tput cup 19 10
read -p "Please Enter a UserName: " uname
这就是我所拥有的一切。有谁知道我该怎么做?
答案1
让我们以此作为示例输入文件:
$ cat file
jim|process1|23
bob|process2|5
jim|process3|7
使用 awk
现在,让我们创建这个 shell 脚本:
$ cat script.sh
#!/bin/sh
read -p "Please Enter a UserName: " uname
awk -v n="$uname" -F\| '$1==n{total+=$3} END{printf "Total for %s is %s minutes\n",n,total}' file
作为一个例子,我们来总结一下 jim 使用的时间:
$ sh script.sh
Please Enter a UserName: jim
Total for jim is 30 minutes
怎么运行的
awk 隐式循环输入文件中的每一行。该脚本使用两个变量:n
哪个是用户名,total
哪个是 user 使用的总分钟数n
。
-v n="$uname"
这将创建一个 awk 变量
n
并将 shell 变量的值赋给它uname
。-F\|
这告诉 awk 用作
|
字段分隔符$1==n{total+=$3}
每次第一个字段
$1
与用户名 匹配时n
,我们都会将总数增加total
第三个字段 的数量$3
。END{printf "Total for %s is %s minutes\n",n,total}
当我们读完文件后,我们打印出结果。
使用外壳
或者,我们可以在 shell 中进行循环:
$ cat script2.sh
#!/bin/sh
read -p "Please Enter a UserName: " uname
while IFS=\| read -r name process minutes; do
[ "$name" = "$uname" ] && total=$((total+minutes))
done <file
echo "Total for $uname is $total minutes"
作为演示:
$ sh script2.sh
Please Enter a UserName: jim
Total for jim is 30 minutes
我没有对这两种方法进行计时,但我预计这种方法awk
会更快。