我有2个文件:
- 一个充满我想要查找的值的文件
- 我的源文本文件
我编写了一个简短的 shell 命令来循环遍历我的值列表并针对我的源文件进行 grep。如果在文件中找不到该值,我想打印该值。
问题是它打印每个值,所以我没有正确地 grep 值,因此它总是不匹配,然后打印该值。希望有人能告诉我我做错了什么。提前致谢。
这是我的脚本
for i in `cat uniq_val.out`
do
found=`grep "$i" fd.out`
if [ -z "${found}" ]
then
echo $i
fi
done
例如,如果我的 uniq_val.out 包含以下内容:
abc123
def456
ghi789
jkl101112
mno131415
我的 fd.out 包含以下内容:
abc123
def456
mno131415
我希望我的 shell 脚本返回
ghi789
jkl101112
答案1
我建议采用以下不同的方法:
grep -f <(grep -o -f uniq_val.out fd.out) -v uniq_val.out
即内部grep
用作uniq_val.out
模式文件并仅返回匹配的部分;然后,外部 grepgrep
对列表执行这些值的逆运算。
但据我所知-o
,这不是 POSIX。
编辑以下有问题的示例文件:
如果您的两个文件实际上都是仅需要匹配的单行字符串,请反转模式文件的逻辑并用于-x
整行匹配:
grep -vx -f fd.out uniq_val.out
这是符合 POSIX 标准的。
答案2
GNU coreutils 提供了处理(排序的)字符串集的工具。在你的情况下,我建议放弃grep
和 for 循环并comm
改为使用:
$ comm -23 uniq_val.out fd.out
ghi789
jkl101112
man comm
:
comm - 逐行比较两个排序的文件。
-2
和键仅-3
打印comm
FILE1 特有的行。
其他可用于字符串和表集的有用工具包括tr
、sort
和uniq
来准备数据,以及join
、cut
和paste
执行一些简单的操作。这些工具比 universal sed
, grep
and 更简单awk
,更不用说perl
and 了python
。