我有一个案例与此类似,但也有一些差异。
内容列表A:
.co
.best.co
.com
.test.server.cloud.us-east.amazonaws.com
.com.co
.abc.com.co
.jp
.def.museum.hiroshima.jp
.net
.xyz.xxx.yyy.net
.exe
.xyz.exe
# and anything else i want to add
内容列表B:
.bar
.co
.com
.server.cloud.us-east.amazonaws.com
.com.co
.jp
.museum.hiroshima.jp
.net
.xxx.yyy.net
# and anything else i want to add
我想要的是从“listA”中删除那些不以“listB”中出现的内容结尾的行,并且也重复
期望的输出:
.best.co
.test.server.cloud.us-east.amazonaws.com
.abc.com.co
.def.museum.hiroshima.jp
.xyz.xxx.yyy.net
我尝试了一些命令,但它对我不起作用:
grep -vi -f <(sed 's:^\(.*\)$:\\\1\$:' listB ) listA > out
grep -v -f <(sed 's/$/$/' listB ) listA > out
提前致谢
答案1
$ grep -x -f <(sed 's/\./\\./g;s/^/.*/' listB) <(grep -v -F -x -f listB listA)
.best.co
.test.server.cloud.us-east.amazonaws.com
.abc.com.co
.def.museum.hiroshima.jp
.xyz.xxx.yyy.net
解释为两个命令:
1.)grep -v -F -x -f listB listA
从中删除文字重复项listA
并使用此输出作为第二个 的输入grep
。这留下了以下条目listA
:
.best.co
.test.server.cloud.us-east.amazonaws.com
.abc.com.co
.def.museum.hiroshima.jp
.xyz.xxx.yyy.net
.exe
.xyz.exe
(要删除的剩余行:.exe
和.xyz.exe
)
2.)grep -x -f <(sed 's/\./\\./g;s/^/.*/' listB) <(...)
.
转义中的点listB
,添加.*
到开头,然后grep
再次匹配以 中的行结尾的行listB
。输入是第一个的结果grep
。
答案2
# save valid extension from listB
vexts=($(sed "s/^.*\.//g" listB))
# loop over listA and filter desired output
while read line; do
if [[ " ${vexts[@]} " == *" ${line##*.} "* ]] ; then
echo "${line}";
fi
done < listA