我有一个符号列表,例如......
wer
sfe
efo
如何从另一个(非唯一)符号列表中删除这些(唯一)符号的所有实例?
因此在下面的列表中,以 开头的行将wer
被删除两次,sfe
一次:
wer-alskjdfi
efr-4siosejf
rte-alskjdfs
wer-alskjsef
sfe-ooskjdfi
每隔一行都应保持不变,只保留“-”后面的符号和字符:
efr-4siosejf
rte-alskjdfs
我需要使用 sed/awk/grep/bash 或其他命令行工具来执行此操作。我知道如何编写 sed 命令来一次搜索并删除一个值,但是对于 100k+ 个值,我该如何执行此操作?
答案1
如果文件 2 中的每个符号后面都有字符怎么办?我想做同样的事情,但保留尾随字符。
好的,复制一份file2
只包含您要过滤的字段的副本。并且,如果当前file2
有“非唯一符号”立即地后面跟着“尾随字符”(例如efr-42
、rte-17
等),在file2
空格分隔的位置再制作一份副本。以下是根据您提供的示例数据编写的示例命令:
sed 's/\(...\).*/\1/' file2.sorted > file2.symbol_only
sed 's/\(...\)\(.*\)/\1 \2/' file2.sorted > file2.separated
或者
sed 's/\([^-]*\)-.*/\1/' file2.sorted > file2.symbol_only
sed 's/\([^-]*\)\(-.*\)/\1 \2/' file2.sorted > file2.separated
…基于您添加到问题中的新数据。然后comm
像以前一样使用:
comm -13 file1.sorted file2.symbol_only > file2.no_match
…并将符号与尾随字符连接起来:
join file2.no_match file2.separated
如果有必要,请使用另一个sed
来删除您添加的空格。
我想到可以利用这个技巧让输出文件恢复到file2
原来的顺序。
file2
制作一份带有行号的原件副本。- 将符号右侧的行号打乱。
- (以上内容,从命令开始
sort
) - 按原始行号对输出进行排序。
- 去掉行号。
如果您需要帮助请告诉我。
答案2
假设你的列表位于文件中
awk -F- 'NR==FNR {exclude[$1]++; next} !($1 in exclude)' list_of_symbols filename
grep 也是一个选项
grep -v -f <(sed 's/^/^/' list_of_symbols) filename
sed 位在每行的开头添加一个正则表达式锚点。
答案3
您是否需要保留第二个文件的顺序?您能说明一行最多可以重复多少次吗?如果两个问题的答案都是“否”,我建议comm
:
sort file1 file1 > file1.sorted sort file2 > file2.sorted
------------------------------- -------------------------
efo efr
efo rte
sfe sfe
sfe wer
wer wer
wer
comm -13 file1.sorted file2.sorted
efr
rte
file1
包含足够多的in副本file1.sorted
以覆盖 中任何字符串的最大出现次数file2
。
答案4
在对 SED 等一无所知的情况下,我个人伪代码中的基本设计是:
对要删除的字符串列表进行排序(列表 A)
对包含要删除的项目的字符串列表进行排序(列表 B)
对于列表 A 中的每个项目
Repeat until Item (List B) > Item (List A)
if the Item (List B) equals Item (List A)
remove item (List B)
next Item (List B)
Next Item (List A)
注意:“删除”一个项目可能会有问题 - 最好用将项目添加到新项目来替换此行