BASH / sed可从文本文件中的行分隔单词列表中删除重复项

时间:2018-10-24 04:21:58

标签: bash sed grep

我的词汇表很长,每行一个字。有时,有一个重复的单词,出现多次或两次以上。我需要一个简单的代码,该代码将保留单词的第一次出现,但删除其后的所有重复项(及其行)。

  1. 我不想删除任何特殊字符或重新排列任何内容,仅删除单词(每行一个)。保持相同的单词顺序很重要。

  2. 是覆盖原始文件还是保存到新文件,无论哪个“效率更高”都没关系。

  3. 这是一个由行分隔的列表,不是数组,也不由空格或逗号分隔。

  4. 我没有代码开始,希望以BASH解决...

    • sed将是第一选择

    • grep是第二选择

    • 第三种选择类似于for循环

例如:file.txt

apple
banana
car
bicycle
apple
tree
banana
apple
motorcycle

...应成为:

apple
banana
car
bicycle
tree
motorcycle

我看到了一些针对ARRAYS的解决方案,但不是简单的列表,并且可以通过python,js和C语言(而不是BASH)进行回答。如果已经回答了,请告诉我在哪里,我很乐意删除此问题。建议的双。这篇文章使用awk,尽管它是相关且有用的,但它不在本问题的讨论范围之内。

4 个答案:

答案 0 :(得分:3)

这可能对您有用(GNU sed):

ZipFile.CreateDirectory("C:\\Parsa\\1","C:\\Parsa\\1.zip");

在保留空间中保留唯一键列表,如果当前键不在列表中,则将其打印并添加到列表中。

答案 1 :(得分:1)

如果您不太担心维护订单,则可以使用以下简单方法:

sort -u inputFileName >outputFileName

这将消除所有重复项,并在此过程中进行排序。

对于维护基于第一次出现的顺序,它变得更加复杂(并且占用内存)。根据以下示例,在awk中使用关联数组是一种方法:

pax> cat infile
zanzibar
apple
banana
apple
carrot
banana
sausage
apple

awk '{if(x[$1]==0){x[$1]=1;print}}' infile
zanzibar
apple
banana
carrot
sausage

此方法的工作方式是awk会在第一次看到一个单词时存储它被看到的事实并输出该单词。该单词的后续实例将无济于事,因为该单词已被标记为可见。

答案 2 :(得分:1)

纯bash:

#!/bin/bash
declare -g -A lines
while IFS='' read -r line
do
  if [[ "${lines["$line"]}" -ne 1 ]]
  then
    echo "$line"
    lines["$line"]=1
  fi
done

编辑:如果将其制作为独立的可执行脚本,则可以使用dedupe.sh < file.txt进行。如果您想在其中对文件名进行硬编码,可以这样进行:

while ....
  ...
done < file.txt

答案 3 :(得分:-1)

使用sort对文件进行排序后,即可使用uniq删除相邻的重复行。

Man pages uniq

sort unsorted.txt | uniq >> sorted_deduped.txt