我把file1
作为file2
的数据源,现在需要确保file1
中的每一行文本都出现在file2
中(如果有任何遗漏,找出哪些行)。需要注意的是,虽然file1
每行恰好包含一个搜索词,但这些词可以出现在file2
的任何位置,包括单词中间。如果匹配不区分大小写将很有帮助 - 只要file2
中的文本存在即可,无论文本是否大写。
file1
中的行包括空格和各种特殊字符,例如--
。
我把file1
作为file2
的数据源,现在需要确保file1
中的每一行文本都出现在file2
中(如果有任何遗漏,找出哪些行)。需要注意的是,虽然file1
每行恰好包含一个搜索词,但这些词可以出现在file2
的任何位置,包括单词中间。如果匹配不区分大小写将很有帮助 - 只要file2
中的文本存在即可,无论文本是否大写。
file1
中的行包括空格和各种特殊字符,例如--
。
if grep -Fqvf file2 file1; then
echo $"There are lines in file1 that don’t occur in file2."
fi
Grep选项的含义:
-F, --fixed-strings PATTERN is a set of newline-separated fixed strings
-f, --file=FILE obtain PATTERN from FILE
-v, --invert-match select non-matching lines
-q, --quiet, --silent suppress all normal output
awk -f a.awk file1 file2
其中 a.awk
是什么
BEGIN { IGNORECASE=1 }
NR==FNR {
a[$0]++
next
}
{
for (i in a)
if (index($0,i))
delete a[i]
}
END {
for (i in a)
print i
}
file2
中的行。 - user2044638file2
中的行的例子吗? - Håkon Hæglandfile2
中的行,所以它最终会输出 file1
中的所有行(只是顺序不同)。至于某些示例行,大多数行似乎没有什么特别之处,主要是互联网链接,其中一些只有一个单词。 - user2044638(1)
将 a[$0]++
更改为简单的 a[$0]
:: 计数器不是必要的,因为将哈希键设置到数组中已经去重了; (2) 在扫描 file2
之前预先删除 a[""]
; (3)
如果 file2
小于 2 GB
左右,则一次性将其全部加载到 $0
中,使用 FS = RS = "^$"
。根据 RS
的定义,file1
中的测试项也不能包括 \n
,因此通过 index($0, i)
直接检查每个项目是否与完整的 file2
相匹配不会有行交叉风险,并且我们也不会因分割不需要的字段而获得任何好处。 - RARE Kpop Manifestogrep -Fqvf file2 file1
并不完全正确,它存在一些问题,所有问题都源自一个主要问题:比较方向被反转了。我们使用file2
中的每一行来搜索file1
,以确保覆盖了file1
中的所有行。这符合grep的工作方式,而且很优雅,但实际上并没有解决问题。我是在比较两个软件包列表时发现了这一点——一个列表是pacman -Qqe
的输出,另一个是我编译到不同分组中的列表,以简化设置新电脑。我想确保我没有错过任何软件包。file2
包含一个空行,输出将始终为false(即它不会识别缺失的行)。这是因为file2
中的空行将匹配file1
的每一行。因此,对于以下文件,我们无法正确识别zsh
是否缺失于file2
中:file1 file2
acpi acpi
... ...
r r
... ...
yaourt yaourt
zsh
<EOF> <EOF>
$ grep -Fvf file2 file1
[ no output ]
$ grep -Fv "$(grep -ve '^&' file2)" file1
zsh
太好了!但是现在我们遇到了另一个问题。假设我们从file2
中删除yaourt
。我们期望的输出结果应该是:
yaourt
zsh
$ grep -Fv "$(grep -ve '^&' file2)" file1
zsh
readarray -t terms < file1 # bash
# zsh: terms=("${(@f)$(< file1)}")
for term in "${terms[@]}"; do # I know `do` "should" be on a separate line; bite me
grep -Fq "$term" file2 ||
{ echo "$term does not appear in file2" && break }
done