从文件/ grep中删除重复的行

时间:2009-09-17 16:11:29

标签: unix shell scripting sorting

我想删除所有第二列05408736032相同的所有行

0009300 | 05408736032 | 89 | 01 | 001 | 0 | 0 | 0 | 1 | NNNNNNYNNNNNNNNN | ASDF | 0009367 | 05408736032 | 89 | 01 | 001 | 0 | 0 | 0 | 1 | NNNNNNYNNNNNNNNN | adff |

这些线不连续。它可以删除所有的线条。我不必保持其中一个。

抱歉,我的unix fu因非使用而非常弱:)。

9 个答案:

答案 0 :(得分:8)

如果所有输入数据的格式如上 - 即固定大小的字段 - 并且输出中的行顺序无关紧要,sort --key=8,19 --unique应该可以解决问题。如果订单确实重要,但重复的行始终是连续的,uniq -s 8 -w 11将起作用。如果字段不是固定宽度但重复行总是连续的,则Pax的awk脚本将起作用。在最常见的情况下,我们可能会看到一些稍微过于复杂的内容,但是。

答案 1 :(得分:3)

假设它们是连续的并且您想要删除后续的,以下awk脚本将执行此操作:

awk -F'|' 'NR==1 {print;x=$2} NR>1 {if ($2 != x) {print;x=$2}}'

它的工作原理是打印第一行并存储第二列。然后对于后续行,它会跳过存储值和第二列相同的行(如果不同,则打印行并更新存储的值)。

如果它们不是连续的,我会选择一个Perl解决方案,你在那里维护一个关联数组来检测并删除重复项 - 我会对它进行编码,但是我的3yo女儿刚刚醒来,现在是午夜,她已经感冒了 - 如果我活了一夜,明天见。:)

答案 2 :(得分:2)

这是用于删除行中重复单词的代码..

awk '{for (i=1; i<=NF; i++) {x=0; for(j=i-1; j>=1; j--) {if ($i == $j){x=1} } if( x != 1){printf ("%s ", $i) }}print ""}' sent

答案 3 :(得分:1)

Unix包含python,因此以下几行可能就是您所需要的:

f=open('input.txt','rt')
d={}
for s in f.readlines():
  l=s.split('|')
  if l[2] not in d:
    print s
    d[l[2]]=True

这可以在不需要固定长度的情况下工作,即使相同的值不是邻居也是如此。

答案 4 :(得分:1)

如果列不是固定宽度,您仍然可以使用sort:

sort -t '|' --key=10,10 -g FILENAME
  1. -t标志将设置分隔符。
  2. -g仅用于自然数字排序。

答案 5 :(得分:0)

这个awk只打印那些第二列不是05408736032

的行
awk '{if($2!=05408736032}{print}' filename

答案 6 :(得分:0)

对输入文件进行两次传递:1)找到重复值,2)删除它们

awk -F\| '
    {count[$2]++} 
    END {for (x in count) {if (count[x] > 1) {print x}}}
' input.txt >input.txt.dups

awk -F\| '
    NR==FNR {dup[$1]++; next}
    !($2 in dup) {print}
' input.txt.dups input.txt

如果你使用bash,你可以省略临时文件:使用进程替换组合成一行:(深呼吸)

awk -F\| 'NR==FNR {dup[$1]++; next} !($2 in dup) {print}' <(awk -F\| '{count[$2]++} END {for (x in count) {if (count[x] > 1) {print x}}}' input.txt) input.txt

(唷!)

答案 7 :(得分:0)

awk -F"|" '!_[$2]++' file

答案 8 :(得分:0)

将行放在哈希中,使用line作为键和值,然后迭代哈希(这应该适用于几乎所有编程语言,awk,perl等)。