我的问题不容易提出,我尝试用以下示例解释问题:
/home/luther/tipical_surnames.txt
Smith
Johnson
Williams
Jones
Brown
#Davis
Miller
Wilson
#Moore
Taylor
Anderson
/home/luther/employers.txt
2000 Johnson A lot-of details / BJC3000,6000, i550 0
2101 Smith A lot-of details / BJC3000,6000, i550 0
2102 Smith A lot-of details / BJC3000,6000, i550 0
2103 Jones A lot-of details / BJC3000,6000, i550 0
2104 Johnson A lot-of details / BJC3000,6000, i550 0
2100 Smith A lot-of details / BJC3000,6000, i550 0
我有一个最喜欢的姓氏列表和另一个雇主姓名的列表。 让我们使用控制台检查公司中有多少人拥有最受欢迎的姓氏:
grep -v "#" /home/luther/tipical_surnames.txt | sed -n 1'p' | cut -f 1
Smith
grep Smith /home/luther/employers.txt | wc -l
230
工作完美。 现在让我们使用简单的bash脚本检查前5个最受欢迎的姓氏:
#!/bin/bash
counter=1
while [ $counter -le 5 ]
do
surname=`grep -v "#" /home/luther/tipical_surnames.txt | sed -n "$counter"'p' | cut -f 1`
qty=`grep "$surname" /home/luther/employers.txt | wc -l`
echo $surname
echo $qty
counter=$(( $counter + 1 ))
done
结果如下:
Smith
0
Johnson
0
Williams
0
Jones
0
Brown
0
怎么了?
更新 就像我写的那样,我在其他计算机上测试了脚本,一切正常。 在我尝试以下后:
root@problematic:/var/www# cat testfile.bash
#!/bin/bash
for (( c=1; c<=5; c++ ))
{
echo $c
}
root@problematic:/var/www# bash testfile.bash
testfile.bash: line 2: syntax error near unexpected token `$'\r''
'estfile.bash: line 2: `for (( c=1; c<=5; c++ ))
root@problematic:/var/www# echo $BASH_VERSION
4.2.37(1)-release
root@problematic:/var/www#
当然在其他计算机上,这个简单的脚本按预期工作,没有错误。
答案 0 :(得分:2)
这显然未经测试,因为您尚未发布样本输入,但这是您应该使用的方法:
awk '
NR==FNR { if (!/#/) cnt[$1]=0; next }
{ cnt[$WHATEVER]++ }
END {
PROCINFO["sorted_in"] = "@val_num_desc"
for (name in cnt) {
print name, cnt
if (++c == 5) {
break
}
}
}
' /home/luther/tipical_surnames.txt /home/luther/employers.txt
将“WHATEVER”替换为雇员姓氏存储在employer.txt中的字段编号。
上面使用GNU awk for sorted_in,其他awks我只是从输出循环中移除PROCINFO行和计数并将输出管道排序然后排序,例如:
awk '
NR==FNR { if (!/#/) cnt[$1]=0; next }
{ cnt[$WHATEVER]++ }
END {
for (name in cnt) {
print name, cnt
}
}
' /home/luther/tipical_surnames.txt /home/luther/employers.txt | sort -k2,1nr | head -5
或任何正确的排序选项。
答案 1 :(得分:0)
我其实不太确定。我测试了你的脚本,通过复制和粘贴它,用想象的数据(/usr/share/dict/words
),它似乎按预期工作。我想知道您发布的脚本与您正在运行的脚本之间是否存在差异?
在此期间,我冒昧地让它运行得更顺畅。请注意,在循环中,您是如何在每次迭代中读取整个姓氏文件的?此外,grep
+ wc -l
可能会被grep -c
取代。我还在-F
的第一次调用中添加grep
,因为模式(#
)是固定字符串。员工档案中的grep
使用\<$name\>
来确保在$name
为John
时我们只收到Johns而没有Johnssons。
#!/bin/bash
employees_in="/usr/share/dict/words"
names_in="/usr/share/dict/words"
grep -v -F "#" "$names_in" | head -n 5 | cut -f 1 |
while read -r name; do
count="$( grep -c "\<$names\> " "$employees_in" )"
printf "name: %-10s\tcount: %d\n" "$name" "$count"
done
测试它:
$ bash script.sh
name: A count: 1
name: a count: 1
name: aa count: 1
name: aal count: 1
name: aalii count: 1
注意:我只获得计数中的一个,因为字典(不足为奇)只包含唯一的单词。