我有一个 while 循环,它接受一个文本文件作为输入(uniq.txt)并使用 grep 查找另一个文件(stage.txt)中的重复项,然后将重复项的数量和该行的内容写入另一个文件 Output.txt 。
由于某种原因, while 循环在文件中途随机停止?
while read line; do
results=$(grep ${line} ./stage.txt | wc -l)
printf '%s\n' "$line $results" >> Output.txt
done < uniq.txt
这就是问题所在。我的 while 循环停在 -b 处。
apps
archive.
AWACP
awac-pri
-b
backup
bad_file
bak.path
BasicPlu
答案1
您的循环停止于,-b
因为此时${line}
被解释为-b
的选项grep
。为了防止这种情况,您需要添加--
, 来告诉grep
不要寻找更多选项:
results=$(grep -- "$line" ./stage.txt | wc -l)
答案2
该问题来自一个变量,该变量获取的值看起来像命令行标志,如下所示佐藤桂指出。
然而,你正在做的事情也可以用,
awk 'NR==FNR {p[++i]=$0;next} {for (i in p){if (match($0,p[i])){c[i]++}}} END {for (i in p){print p[i],c[i]}}' uniq.txt stage.txt >output.txt
...如果模式的数量uniq.txt
不是数百万。
剧本awk
揭晓:
NR==FNR { p[++i] = $0; next }
{
for (i in p) {
if (match($0, p[i])) {
c[i]++
}
}
}
END {
for (i in p) {
print p[i],c[i]
}
}
它首先将 的每一行读uniq.txt
入数组p
,然后继续计算(在数组中c
)第二个文件中包含每个模式的输入行数p
。
最后,输出模式和相应的计数。
这避免了慢的shell 循环(对每个模式执行grep
一次wc
,并且多次打开和写入输出文件),并且还避免了必须使用read
.
如果您想进行固定字符串匹配,即不将 中 的行uniq.txt
视为正则表达式模式,而是视为固定字符串(与 一样grep -F
),只需将match($0, p[i])
函数调用更改为index($0, p[i])
.