我想获取一个字符串列表,并仅保留列表中其他地方没有子字符串的字符串。为了说明这一点,我有这个列表:
apple
applesauce
kiwi
mango
mangoes
mangosteen
oranges
pineapples
我想将其缩减为一个字符串列表,该列表中的其他位置没有任何子字符串。因此,结果列表将是:
apple
kiwi
mango
oranges
请注意,applesauce
和 pineapples
已被删除,因为 apple
位于列表中的其他位置,并且是这两个单词的子字符串。
我发现了类似的问题here但它似乎专门针对前缀,例如闪耀,能干,能干,最能干
。基于该方法,我对列表的预排序副本尝试了以下操作,它只是打印了整个列表,甚至没有删除我认为会删除的 applesauce
:
awk '$1~r && p in k { next } { k[$1]++; print; r= "^" $1; p=$1 }' fruitsorted.txt
即使它按照我的预期工作,它仍然会错过我的列表中的pineapple
。
请注意,在极端情况下,如果列表包含字母表中的所有字母(我猜是 ASCII 字符集),每个字母都在单独的行上,那么无论列表中还有什么,输出都将是字母/字符集。
此外,我的起始列表未排序。我并不关心结果列表是否已排序,尽管这对于 sort
来说显然是微不足道的。
理想情况下,我想要一个稍微紧凑的 shell 命令/诸如 grep/sort/awk 之类的东西序列,而不是更长的 Perl/Python/任何我已经知道如何实现的脚本。
谢谢。
更新
正如埃德·莫顿(Ed Morton)在下面指出的那样,即使对列表进行排序也可能会扰乱一些基本方法,例如在以下示例中,假设排序列表的方法可能无法删除 berryplum
,因为其子字符串 plum
位于其后面。 123 所示的第二种方法可以处理这种情况。
apple
applesauce
berryplum
kiwi
mango
mangoes
mangosteen
oranges
pineapples
plum
最佳答案
如果列表已排序,那就非常简单
awk '{for(i in a)if(index($0,i))next;a[$0]}1' file
apple
kiwi
mango
oranges
基本上只是循环遍历每行的数组,并检查该行中是否存在元素。如果不是这种情况,则添加到数组。
对于未排序的列表,这应该有效
awk '{for(i in a){if(index(i,$0)&&$0!=i)delete a[i];if(index($0,i))next}a[$0];next}
END{for(i in a)print i}' file
在 Wordlist 上测试为了性能。
real 0m29.932s
user 0m29.918s
sys 0m0.008s
关于Linux:如果字符串在列表中其他位置有子字符串,则从列表中删除字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44722588/