Bash 基于子字符串后缀从文件中删除重复项

Bash 基于子字符串后缀从文件中删除重复项,bash,shell,Bash,Shell,假设我的文件中有以下文本: foo.bar.baz bar.baz 123.foo.bar.baz pqr.abc.def xyz.abc.def abc.def.ghi.jkl def.ghi.jkl 如何根据后缀从文件中删除重复项?无重复项的预期输出为: bar.baz pqr.abc.def xyz.abc.def def.ghi.jkl (考虑foo.bar.baz和bar.baz。后者是一个子字符串后缀,因此只有bar.baz保留。但是,pqr.abc.def和xyz.abc.de

假设我的文件中有以下文本:

foo.bar.baz
bar.baz
123.foo.bar.baz
pqr.abc.def
xyz.abc.def
abc.def.ghi.jkl
def.ghi.jkl
如何根据后缀从文件中删除重复项?无重复项的预期输出为:

bar.baz
pqr.abc.def
xyz.abc.def
def.ghi.jkl
(考虑
foo.bar.baz
bar.baz
。后者是一个子字符串后缀,因此只有
bar.baz
保留。但是,
pqr.abc.def
xyz.abc.def
都不是彼此的子字符串后缀,因此两者都保留。)

尝试以下方法:

#!/bin/bash

INPUT_FILE="$1"

in="$(cat $INPUT_FILE)"
out="$in"

for line in $in; do
  out=$(echo "$out" | grep -v "\.$line\$")
done

echo "$out"
您需要将其保存到脚本(例如,
bashor.sh
),使其可执行(
chmod+x bashor.sh
),并使用输入文件作为第一个参数调用它:

./bashor.sh path/to/input.txt

使用
sed
对正则表达式、前缀
、后缀
$
的字符串进行转义,并将其导入GNU grep(
-f-
不适用于BSD grep,例如在mac上)


我只是习惯了,没有考虑它是否合理。乍一看似乎不错,但逃避太多,尽管这可能不是问题。

你能更准确一点吗?我不明白这里的模式。@dstronczak,我试着解释得更好一点,也许这现在就有意义了。我想出了一个类似的解决方案。不过您有一个bug:grep将
解释为任何字符,因此您必须对其进行转义:裸
$line
中的点(即,假设没有其他特殊字符,前缀总是用点分隔)实际上,如果只有三个字符标记,我的解决方案就可以了(我故意使用了
a通配符)。但这当然是一个疯狂的假设,所以我避开了问题中的
。。是的,这是一个疯狂的假设。如果不是,
a.a
将匹配
aaa
。我更担心的是逃跑。。。
sed 's/[^-A-Za-z0-9_]/\\&/g; s/^/./; s/$/$/' test.txt |grep -vf - test.txt