You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何删除文件中顺序相反的重复单词对?

解决方法:移除反向单词对,保留指定顺序的条目

嘿,我来帮你搞定这个问题!先分析下你现有代码的问题,再给出针对性的解决方案:

你的原有代码为啥没输出?

这里有两个关键问题:

  • 如果你的文件是单行文本,while read f1 f2只会读取该行的前两个单词,剩下的内容根本不会进入循环处理——因为read默认是按行读取,不是按单词对拆分的。
  • 在awk命令里,你直接用了shell变量$f1和$f2,但awk不认这种写法!shell变量要传递给awk得用-v参数,不然awk会把$f2当成字段索引(比如$dog,这显然是无效的),导致判断逻辑永远不成立,自然没输出。

方案1:文件每行是单个单词或单词对(更符合你代码的使用场景)

如果你的文件结构是每行要么两个单词、要么单个单词(比如:

cat dog
mouse
cat dog
dog cat
mouse

),要删除dog cat这类反向对、保留cat dog,直接用下面的awk命令就行:

awk '
    # 处理两个单词的行
    NF == 2 {
        # 精准匹配要删除的反向对:dog cat
        if ($1 == "dog" && $2 == "cat") {
            next  # 跳过该行,不输出
        }
        # 其他符合要求的对直接输出
        print
        next
    }
    # 单个单词的行直接输出
    NF == 1 {print}
' file

执行后就能得到你想要的结果:

cat dog
mouse
cat dog
mouse

要是你想通用处理所有反向对(比如不管是什么单词,只保留第一个单词字典序更小的那组,比如a b留、b a删),可以改成:

awk '
    NF == 2 {
        if ($1 > $2) next  # 第一个单词比第二个大就跳过
        print
        next
    }
    NF == 1 {print}
' file

方案2:文件是单行文本(符合你给出的示例输入)

如果你的输入是单行文本(比如cat dog mouse cat dog dog cat mouse),要移除其中的dog cat,用sed最直接:

# 先删除所有dog cat,再清理多余空格
sed 's/dog cat//g; s/  */ /g; s/^ //; s/ $//' file

执行后输出就是你要的:

cat dog mouse cat dog mouse

也可以用awk来做更灵活的处理:

awk '
    BEGIN {OFS=" "}
    {
        for (i=1; i<=NF; i++) {
            # 检查当前和下一个单词是不是要删除的反向对
            if ($i == "dog" && $(i+1) == "cat") {
                i++  # 跳过下一个单词
                continue
            }
            # 把符合要求的单词加入结果
            res = res $i OFS
        }
        # 去掉末尾多余的空格再输出
        sub(/ '$'/, "", res)
        print res
    }
' file

补充:怎么正确在awk里用shell变量?

如果你非要用原来的循环思路,得把shell变量传递给awk,比如:

cat file | while read f1 f2; do awk -v a="$f1" -v b="$f2" '($1==b) && ($2==a)' file; done

但这种方法效率极低(循环一次就读一遍整个文件),逻辑上也容易重复输出,所以完全不推荐用这种方式。

内容的提问来源于stack exchange,提问作者Swimming bird

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:14:51