Como remover pares de correspondência inversa?

2

Eu quero remover pares de correspondência duplicados / inversos de um arquivo de texto.

Por exemplo, o arquivo contém dados como os abaixo:

10 |Name1 |20 |Name2
20 |Name2 |30 |Name3
20 |Name2 |10 |Name1   <-- Inverse pair (compared to first line) to be removed from text file
40 |Name4 |30 |Name3

Espero que o resultado seja o seguinte:

10 |Name1 |20 |Name2
20 |Name2 |30 |Name3
40 |Name4 |30 |Name3
    
por Kiran 06.09.2018 / 22:19

3 respostas

3

com awk:

awk -F '[[:blank:]]*[|][[:blank:]]*' -v SUBSEP='|' '
    ($1,$2,$3,$4) in seen || ($3,$4,$1,$2) in seen {next} 
    {seen[$1,$2,$3,$4]; print}
' file

Isso define o separador de campo para o caractere de barra com espaço em branco inicial ou final opcional. Em seguida, ele procura os "pares" como chaves de matriz associativas, em qualquer ordem: se encontrado, pule esta linha; caso contrário, adicione a chave ao array e imprima a linha.

    
por 06.09.2018 / 23:05
1

Talvez algo como:

perl -F'[|]' -lane '
  for (@F) {
    # trim the fields to remove leading and trailing blanks
    s/^\s+//; s/\s+$//
  }
  # re-join the trimmed fields into $a
  my $a = join "|", @F[0..3];

  # same, inverting the two pairs into $b
  my $b = join "|", @F[2,3,0,1];

  # print unless either $a or $b has been seen before
  print unless $seen{$a} || $seen{$b}++' < your-file

Para generalizar para qualquer número de pares encontrados em qualquer ordem, você deve classificar esses pares para criar a chave da matriz %seen associativa:

perl -F'[|]' -lane '
  for (@F) {
    # trim the fields to remove leading and trailing blanks
    s/^\s+//; s/\s+$//
  }

  my @pairs;
  while (my ($a, $b) = splice(@F, 0, 2)) {
    push @pairs, "$a|$b"
  }
  my $key = join "|", sort @pairs;

  print unless $seen{$key}++' < your-file
    
por 06.09.2018 / 22:50
0

Você pode fazer isso com sed. O código abaixo está usando gnu sed, mas pode ser prontamente posix compatível.

sed -Ee '
   $!{
      s/$/|/
      N
      s/[[:blank:]]+//g
      H;s/.*//;x;D
   }
   s/$/|/
   G;H;g
   y/\n_/_\n/
   :xdup
       s/_((([^_|]+[|]){2})(([^_|]+[|]){2}))_(.*_)?_/__/
   txdup
   s/^_//;s/_$//
   y/\n_/_\n/
'  input.csv

Será explicado mais tarde, à medida que a hora do rush se aproximar

Resultados:

10|Name1|20|Name2|
20|Name2|30|Name3|
40|Name4|30|Name3| 
    
por 07.09.2018 / 04:48