Linux 合并两个没有伪重复的文件

Linux 合并两个没有伪重复的文件,linux,command-line,awk,sed,Linux,Command Line,Awk,Sed,我有两个文本文件file1.txt和file2.txt,它们都包含这样几行字: 票价 单词 单词ed 沃德 工作 及 法尔 文本 安塞尔 编织 工作 措辞 或者类似的事情。我所说的一个词,是指一系列可能带有重音的字母a-z,以及符号-。我的问题是,如何从linux命令行(使用awk,sed等)中创建满足以下三个条件的第三个文件output.txt: 如果两个文件中出现相同的单词,则第三个文件output.txt只包含一次 如果文件中某个单词的连字符版本(例如file2.txt中的fa-r

我有两个文本文件
file1.txt
file2.txt
,它们都包含这样几行字:

票价
单词
单词ed
沃德
工作


法尔
文本
安塞尔
编织
工作
措辞
或者类似的事情。我所说的一个词,是指一系列可能带有重音的字母a-z,以及符号
-
。我的问题是,如何从linux命令行(使用
awk
sed
等)中创建满足以下三个条件的第三个文件
output.txt

  • 如果两个文件中出现相同的单词,则第三个文件
    output.txt
    只包含一次
  • 如果文件中某个单词的连字符版本(例如file2.txt中的
    fa-re
    )出现在另一个文件中,则output.txt中仅保留连字符版本(例如,在我们的示例中仅保留
    fa-re
  • 因此,output.txt应包含以下文字:
    
    法尔
    单词
    单词ed
    沃德
    工作
    文本
    安塞尔
    

    ======================编辑========================

    我已经修改了文件,并给出了输出文件。 我将尝试手动确保没有不同的连字号(例如wod ed和wod)。

    Awk解决方案 崩溃 仅当第一个字段尚未作为关键字驻留在数组
    字中时,才处理该行


    使用
    -
    作为分隔符,将第一个字段拆分为数组
    f
    。单词的第一部分和第二部分分别位于
    f[1]
    f[2]
    中。如果单词没有连字符,它将完整地驻留在
    f[1]


    通过连接单词的第一部分和第二部分,将脱酚单词指定给
    w
    。如果单词最初没有连字符,结果将是相同的,因为
    f[2]
    为空


    words
    数组中,将非缩略词作为关键字存储。如果单词被连字符(
    f[2]
    不是空的),则将其存储为键的值


    处理完文件后,遍历
    单词
    数组,如果键包含值(带连字符的单词),则打印它,否则打印键(不带连字符的单词)。

    另一个awk:

    !($1 in a) || $1 ~ "-" { 
        key = value = $1; gsub("-","",key); a[key] = value 
    }
    END { for (i in a) print a[i] }
    
    $ awk -f npr.awk file1.txt file2.txt
    text
    word-ed
    uncial
    wor
    wo-ded
    word
    fa-re
    

    这并不完全是你所要求的,但也许更适合你的需要

    awk '{k=$1; gsub("-","",k); w[k]=$1 FS w[k]} END{for( i in w) print w[i]}'
    
    这将按等价类(不带连字符的匹配)对文件中的所有单词进行分组。你可以从这个结果中获得另一个通行证,以获得你想要的

    uncial
    word
    woded wo-ded 
    wor wor
    worded word-ed
    text
    fa-re fare
    
    优点是不需要手动检查是否有可选的连字号,也不需要查看每个单词有多少个不同的实例。 例如,这将过滤掉上一个列表以获得所需的输出

    awk '{w=$1; for(i=1;i<=NF;i++) if(match($i,/-/)!=0)w=$i; print w}'
    

    awk'{w=$1;用于(i=1;iStep 1很简单--
    cat file1.txt file2.txt | uniq>output.txt
    。你能给我举一些步骤2的例子吗?这相当混乱。你能解释一下为什么要这样做吗?保留重复的连字符版本似乎很奇怪。谢谢你的步骤1。我想从输出中删除所有未连字符的版本,但请继续如果存在连字号版本,则仅此而已。第2步太复杂,无法在命令行的sed/awk/perl中清晰地实现。这需要一个小脚本。正如我所解释的,第2步不是必需的,我只想在存在连字号的情况下删除未连字号,即如果
    fare
    fare
    都出现在m中y文件,我想删除
    费用
    。不要给我们一堆
    类似的东西
    -给我们具体、精确、可测试的输入和预期的输出。
    w = f[1] f[2]
    
    if (f[2])
        words[w] = $1
    else
        words[w]
    
    END {
        for (k in words)
            if (words[k])
                print words[k]
            else
                print k
    }
    
    !($1 in a) || $1 ~ "-" { 
        key = value = $1; gsub("-","",key); a[key] = value 
    }
    END { for (i in a) print a[i] }
    
    $ awk -f npr.awk file1.txt file2.txt
    text
    word-ed
    uncial
    wor
    wo-ded
    word
    fa-re
    
    awk '{k=$1; gsub("-","",k); w[k]=$1 FS w[k]} END{for( i in w) print w[i]}'
    
    uncial
    word
    woded wo-ded 
    wor wor
    worded word-ed
    text
    fa-re fare
    
    awk '{w=$1; for(i=1;i<=NF;i++) if(match($i,/-/)!=0)w=$i; print w}'