如何从另一个列表中删除一个列表中出现的所有值?

如何从另一个列表中删除一个列表中出现的所有值?

我有一个符号列表,例如......

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-42rte-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原来的顺序。

  1. file2制作一份带有行号的原件副本。
  2. 将符号右侧的行号打乱。
  3. (以上内容,从命令开始sort
  4. 按原始行号对输出进行排序。
  5. 去掉行号。

如果您需要帮助请告诉我。

答案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)

注意:“删除”一个项目可能会有问题 - 最好用将项目添加到新项目来替换此行

相关内容