selecionando linhas que possuem o mesmo valor [closed]

1

Eu tenho um problema na seleção de linhas que possuem o mesmo valor. Meus dados são muito grandes para ir de fila em fila para fazer isso. Eu quero que vocês me digam scripts que possam fazer isso.

Meus dados são parecidos com os abaixo:

nome do arquivo: temp

Start day   hour    end day        hour Value
01/04/2000  22:00   01/05/2000  09:00   -9
01/05/2000  09:00   01/06/2000  09:00   -9
01/06/2000  09:00   01/07/2000  09:00   -9
01/07/2000  09:00   01/08/2000  09:00   -9
01/08/2000  09:00   01/09/2000  09:00   -9
01/09/2000  09:00   01/10/2000  09:00   -9
01/10/2000  09:00   01/11/2000  09:00   -9
01/11/2000  09:00   01/11/2000  21:30   -9
01/11/2000  22:30   01/12/2000  09:00   -9
01/12/2000  09:00   01/13/2000  09:00   -9
01/15/2000  09:00   01/16/2000  09:00   -9
01/16/2000  09:00   01/17/2000  09:00   -9
01/17/2000  09:00   01/18/2000  09:00   -9
01/18/2000  09:00   01/18/2000  22:45   -9
01/18/2000  22:50   01/19/2000  09:00   0.15
01/19/2000  09:00   01/20/2000  09:00   -9
01/20/2000  09:00   01/21/2000  09:00   -9
01/21/2000  09:00   01/22/2000  09:00   -9
01/22/2000  09:00   01/23/2000  09:00   -9
01/23/2000  09:00   01/24/2000  09:00   -9
01/24/2000  09:00   01/25/2000  09:00   -9
01/25/2000  09:00   01/26/2000  00:35   -9
01/26/2000  00:35   01/26/2000  09:00   -9
01/26/2000  09:00   01/27/2000  09:00   -9

Acima de 18/01/2000, por exemplo, aparece duas vezes como o "dia de início" e duas vezes como "dia final". Portanto, quero incluir as linhas que têm 01/18/2000 como o "dia de início" ou "dia de término".

Eu quero que minha saída dos dados acima seja:

Start day   hour    end day        hour Value
01/10/2000  09:00   01/11/2000  09:00   -9
01/11/2000  09:00   01/11/2000  21:30   -9
01/11/2000  22:30   01/12/2000  09:00   -9
01/17/2000  09:00   01/18/2000  09:00   -9
01/18/2000  09:00   01/18/2000  22:45   -9
01/18/2000  22:50   01/19/2000  09:00   0.15
01/25/2000  09:00   01/26/2000  00:35   -9
01/26/2000  00:35   01/26/2000  09:00   -9
01/26/2000  09:00   01/27/2000  09:00   -9
    
por AiB 24.08.2013 / 00:53

3 respostas

1

Se bem entendi, você quer linhas cujas datas de início ou término são duplicadas. Então talvez algo como:

awk 'NR==FNR{s[$1]++;e[$3]++;next}
     FNR == 1 || s[$1]>1 || e[$3]>1' temp temp

Isso é fazer duas passagens no arquivo. Na primeira passagem, conte o número de ocorrências das datas inicial e final e, na segunda passagem, imprima as linhas em que o número de ocorrências da data inicial ou final é maior que 1.

    
por 24.08.2013 / 10:22
0

Se for simplesmente linhas com as mesmas datas de início e término (e sem referência à linha anterior):

perl -ne 'print if(m!^(\d{2}/\d{2}/\d{4})\s+\d{2}:\d{2}\s+!);' < file

^ início da linha

(\d{2}/\d{2}/\d{4}) correspondem à data e à loja (para que possamos referenciá-lo com )

\s+\d{2}:\d{2}\s+ 1 ou mais espaços 2 dígitos a dois dígitos 2 e, em seguida, 1 ou mais espaços

"backreference" a data armazenada

Se isso corresponder, print da linha.

    
por 24.08.2013 / 04:28
0

Eu montei um script Perl que, esperançosamente, faz o que você está procurando. Ele supõe que os dados que você forneceu em seu exemplo estão em um arquivo chamado temp .

#!/usr/bin/perl

### ./timetract.pl

## 01/10/2000  09:00   01/11/2000  09:00   -9
## 01/11/2000  09:00   01/11/2000  21:30   -9
## 01/11/2000  22:30   01/12/2000  09:00   -9
## ...
## 01/17/2000  09:00   01/18/2000  09:00   -9
## 01/18/2000  09:00   01/18/2000  22:45   -9
## 01/18/2000  22:50   01/19/2000  09:00   0.15
#  ...
## 01/25/2000  09:00   01/26/2000  00:35   -9
## 01/26/2000  00:35   01/26/2000  09:00   -9
## 01/26/2000  09:00   01/27/2000  09:00   -9
## 01/27/2000  09:00   01/28/2000  09:00   -9

use strict;
use warnings;
use feature qw( say );

open (my $fh, "<", "temp") || die "Can't open temp: $!";

my ($prevEndDate, @middleRow, $s1, $s2, $mRow) = "";

for my $cRow (<$fh>) {
  chomp($cRow);

  my @currentRow = split(/\s+/, $cRow);
  next if $currentRow[0] =~ /Start/;  # skip first row

  ## col1        col2    col3        col4    col5
  ## ----        ----    ----        ----    ----
  ## 01/27/2000  09:00   01/28/2000  09:00   -9

  # identify that we're on the last row of a block that
  # we're interested in, print it, reset & go to the next row
  if ($currentRow[0] eq $prevEndDate && $s2) {
    say $cRow;
    $s1 = $s2 = 0; # reset states, get ready for next block
    next;
  }

  # identify that we're in the middle of a block that
  # we're interested in, so save current row as a middle row
  if ($currentRow[0] ne $currentRow[2]) {
    $prevEndDate = $currentRow[2];  
    @middleRow   = @currentRow;
    $mRow        = $cRow;
    next;
  }

  # identified beginning row of a block of rows that we're interested in
  $s1 = 1 if ($prevEndDate eq $currentRow[0]);
  # identified middle row of a block of rows that we're interested in
  $s2 = 1 if ($s1 == 1 && $currentRow[0] eq $currentRow[2]);

  say $mRow;
  say $cRow;
}

close ($fh);

# vim: set ts=2 nolist :

Quando você executá-lo, verá a seguinte saída:

$ ./timeextract.pl 
01/10/2000  09:00   01/11/2000  09:00   -9
01/11/2000  09:00   01/11/2000  21:30   -9
01/11/2000  22:30   01/12/2000  09:00   -9
01/17/2000  09:00   01/18/2000  09:00   -9
01/18/2000  09:00   01/18/2000  22:45   -9
01/18/2000  22:50   01/19/2000  09:00   0.15
01/25/2000  09:00   01/26/2000  00:35   -9
01/26/2000  00:35   01/26/2000  09:00   -9
01/26/2000  09:00   01/27/2000  09:00   -9
    
por 24.08.2013 / 07:41