好吧,我有两个文件夹。为了简单起见,我将它们称为players
和items
。 items 文件夹包含每个项目的文件,people 文件夹包含每个人的文件,其中包含该人拥有的动物的引用。这是我到目前为止所拥有的:
ls -1 ~/items | cut -d. -f1 | grep -R -f - ~/player
我从中得到的 grep 语法这里。我试图让它说:
electric: 8
laser: 7
loltrail: 2
相反,我添加-c
标志grep
并得到:
Bob.txt: 0
Cathy.txt: 0
John.txt: 0
Patrick.txt: 1
如何获得物品总数,而不是每个人的物品数量?
这是为了弄清楚有多少项目正在使用点商店Garry's Mod 的插件。
答案1
以下是使用 GNU 获得所需结果的方法awk
:
awk '
BEGINFILE {
if (FILENAME ~ "^animals/" || FILENAME ~ "/animals/") {
this_name = substr(FILENAME, index(FILENAME,"animals/")+length("animals/"))
i = index(this_name, ".")
if (i > 0) this_name = substr(this_name, 1, i-1)
critter[++num] = this_name
critter_count[num] = 0
nextfile
}
}
{
for (i = 1; i <= num; i++) {
if ($0 ~ critter[i]) critter_count[i]++
}
}
END {
for (i = 1; i <= num; i++) print critter[i] ": " critter_count[i]
}
' animals/* people/*
启动新文件 (
BEGINFILE
) 时,检查其名称是否以 开头animals/
或包含/animals/
.这让你可以说animals/*
,./animals/*
, 或~/animals/*
。如果是的话,- 提取 右侧的子字符串
animals/
。 - 然后寻找一个
.
;如果找到,则提取其左侧的子字符串。 - 将此字符串(基本文件名,删除目录和扩展名)添加到
critter[]
数组中,并将相应的初始化critter_count
为0。
☛ 请注意,
BEGINFILE
和nextfile
在 POSIX awk 中不可用。- 提取 右侧的子字符串
- 否则(如果我们正在查看一个
people
文件),循环遍历动物名称critter
并计算与它们匹配的行数。 - 到达
END
所有输入后,报告从文件名称中提取的动物名称animals
,以及每个动物名称在文件中出现的频率people
。
这不会people
递归地搜索目录;我在问题中没有看到任何所需的陈述。
答案2
我认为如果您将模式作为grep
using的输入stdin
,它将连接所有模式的结果。所以据我所知,解决这个问题的唯一方法是为每个模式调用一个新的 grep 实例。
这个脚本在这种情况下可以工作
for animalName in $(ls -1 ~/animals | cut -d. -f1);
do
echo "$animalName: $(grep -R -h -c $animalName ~/people | paste -sd+ | bc)";
done
这与您尝试过的一些细微更改相符。首先,-h
选项 ingrep
禁止打印文件名。其次,仅使用grep
,模式的输出将类似于
1
0
3
2
我们想要将所有这些数字相加。paste
命令用 a 连接这些行+
,然后将形成的字符串传递给 来bc
计算结果。
注意:如果您的动物名称包含换行符或任何特殊字符(在某些陌生的地方),则不建议解析ls
.