文本处理:基于第二列筛选排序文件,移除fileA中不匹配fileB的行
这里有几个高效且实用的方法来解决你的问题,针对不同场景可以灵活选择:
先明确问题场景
我们有两个文件:
fileA内容:
232 com.path.class1 32 com.path.class2 123 com.path.class3fileB内容:
675 com.path.class6 567 com.path.class2 657 com.path.class1需求:移除
fileA中第二列(类名)未在fileB第二列出现过的行,且已知fileA的行数多于fileB。
方法1:用join命令(大文件首选,效率最高)
join是专门处理已排序文件的工具,如果你能确保两个文件按第二列排序(或先做排序处理),这是最优解:
# 如果原文件未按第二列排序,先排序再join join -1 2 -2 2 -o 1.1,1.2 <(sort -k2 fileA) <(sort -k2 fileB)
参数解释:
-1 2:指定第一个输入文件(这里是排序后的fileA)的连接字段为第2列-2 2:指定第二个输入文件(排序后的fileB)的连接字段为第2列-o 1.1,1.2:只输出fileA的第1、2列(也就是我们需要保留的行)<(sort -k2 文件):用进程替换实现“先排序再传入join”,如果你的文件本来就按第二列排序,直接替换成文件名即可
输出结果:
232 com.path.class1 32 com.path.class2
方法2:用awk命令(灵活通用,无需预先排序)
如果不想处理排序逻辑,或者需要更灵活的过滤规则,awk是绝佳选择:
awk 'NR==FNR {classes[$2]=1; next} $2 in classes' fileB fileA
逻辑解释:
- 当处理第一个文件(
fileB)时,把所有类名存入数组classes - 处理第二个文件(
fileA)时,检查当前行的类名是否在classes数组中,存在则输出该行
这个方法不管文件是否排序都能工作,代码简洁易读,中小文件用起来非常顺手,输出结果和上面一致。
方法3:用grep命令(最简单直接)
如果文件规模不大,用grep可以快速搞定:
grep -Ff <(cut -d' ' -f2 fileB) fileA
逻辑解释:
cut -d' ' -f2 fileB:提取fileB里的所有类名-F:把类名当作固定字符串匹配,避免类名中的特殊字符(比如.)被当作正则符号-f:从提取出的类名列表中读取匹配模式
这个方法代码最短,适合快速验证需求,但大文件下效率不如前两种方法。
内容的提问来源于stack exchange,提问作者Humble Student
相关产品推荐
相关产品推荐

