slh*_*hck 144 linux shell diff grep sed
我有一个大文件A(包含电子邮件),每封邮件一行.我还有另一个包含另一组邮件的文件B.
我将使用哪个命令从文件A中删除文件B中出现的所有地址.
所以,如果文件A包含:
A
B
C
Run Code Online (Sandbox Code Playgroud)
和文件B包含:
B
D
E
Run Code Online (Sandbox Code Playgroud)
然后文件A应该留下:
A
C
Run Code Online (Sandbox Code Playgroud)
现在我知道这是一个可能经常被问到的问题,但我只在网上发现了一个命令错误的分隔符.
任何帮助将非常感激!有人肯定会想出一个聪明的单行,但我不是shell专家.
The*_*aul 187
comm -23 file1 file2
Run Code Online (Sandbox Code Playgroud)
-23会抑制两个文件中的行,或仅抑制文件2中的行.文件必须进行排序(它们在您的示例中)但如果不是,则-23
先将它们通过...
Cir*_*四事件 71
grep -Fvxf <lines-to-remove> <all-lines>
例:
cat <<EOF > A
b
1
a
0
01
b
1
EOF
cat <<EOF > B
0
1
EOF
grep -Fvxf B A
Run Code Online (Sandbox Code Playgroud)
输出:
b
a
01
b
Run Code Online (Sandbox Code Playgroud)
说明:
-F
:使用文字字符串而不是默认的BRE-x
:只考虑匹配整行的匹配项-v
:打印不匹配-f file
:从给定文件中获取模式对于预先排序的文件,此方法比其他方法慢,因为它更通用.如果速度也很重要,请参阅:快速查找一个文件中不在另一个文件中的行?
另见:https://unix.stackexchange.com/questions/28158/is-there-a-tool-to-get-the-lines-in-one-file-that-are-not-in-another
kar*_*kfa 48
拯救!
此解决方案不需要排序输入.你必须先提供fileB.
awk 'NR==FNR{a[$0];next} !($0 in a)' fileB fileA
Run Code Online (Sandbox Code Playgroud)
回报
A
C
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?
NR==FNR{a[$0];next}
idiom用于将第一个文件存储在关联数组中,作为以后"包含"测试的键.
NR==FNR
正在检查我们是否正在扫描第一个文件,其中全局行计数器(NR)等于当前文件行计数器(FNR).
a[$0]
将当前行添加到关联数组作为键,请注意,这表现得像一个集合,其中不会有任何重复值(键)
!($0 in a)
我们现在在下一个文件中,in
是一个包含测试,这里它检查当前行是否在我们从第一个文件的第一步填充的集合中,!
否定条件.这里缺少的是动作,默认情况下{print}
通常不会明确写入.
请注意,现在可以使用此功能删除列入黑名单的单词.
$ awk '...' badwords allwords > goodwords
Run Code Online (Sandbox Code Playgroud)
稍作修改,它可以清理多个列表并创建清理版本.
$ awk 'NR==FNR{a[$0];next} !($0 in a){print > FILENAME".clean"}' bad file1 file2 file3 ...
Run Code Online (Sandbox Code Playgroud)
Pau*_*ce. 17
另一种做同样事情的方法(也需要排序输入):
join -v 1 fileA fileB
Run Code Online (Sandbox Code Playgroud)
在Bash中,如果文件未预先排序:
join -v 1 <(sort fileA) <(sort fileB)
Run Code Online (Sandbox Code Playgroud)
除非对文件进行排序,否则可以执行此操作
diff file-a file-b --new-line-format="" --old-line-format="%L" --unchanged-line-format="" > file-a
Run Code Online (Sandbox Code Playgroud)
--new-line-format
适用于文件b中的行但不适
--old-..
用于文件a中的行而不是b
--unchanged-..
中的行适用于两者中的行.
%L
使它完全打印出来.
man diff
Run Code Online (Sandbox Code Playgroud)
更多细节
对于非常大的文件,@ karakfa很好的答案的这种改进可能会明显更快。与该答案一样,两个文件都不需要排序,但是借助awk的关联数组可以确保速度。仅查找文件保留在内存中。
这种表述还允许比较中仅使用输入文件中的一个特定字段($ N)。
# Print lines in the input unless the value in column $N
# appears in a lookup file, $LOOKUP;
# if $N is 0, then the entire line is used for comparison.
awk -v N=$N -v lookup="$LOOKUP" '
BEGIN { while ( getline < lookup ) { dictionary[$0]=$0 } }
!($N in dictionary) {print}'
Run Code Online (Sandbox Code Playgroud)
(此方法的另一个优点是很容易修改比较标准,例如修剪前和后空白。)