AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 513370
Accepted
user9371654
user9371654
Asked: 2019-04-20 02:19:54 +0800 CST2019-04-20 02:19:54 +0800 CST 2019-04-20 02:19:54 +0800 CST

Removendo linhas cuja primeira coluna está duplicada

  • 772

Eu tenho um arquivo onde as strings são separadas por uma string especial (não uma vírgula ou delimitador), por exemplo <vvv>. Eu quero verificar se todas as strings no primeiro campo são únicas. Se forem encontradas linhas duplicadas para o mesmo campo, desejo remover todas as linhas repetidas (deixe a primeira ocorrência).

Exemplo:

aaa<vvv>bbb<vvv>ccc
xxx<vvv>yyy<vvv>zzz
aaa<vvv>new<vvv>new2
111<vvv>222<vvv>333

Eu quero obter:

aaa<vvv>bbb<vvv>ccc
xxx<vvv>yyy<vvv>zzz
111<vvv>222<vvv>333

Removemos aaa<vvv>new<vvv>new2porque aaajá apareceu.

Eu não prefiro a nós , a awkmenos que seja a única solução. Sua sintaxe é um pouco complexa para mim como um desconhecido para o Linux.

awk sed
  • 4 4 respostas
  • 674 Views

4 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2019-04-20T02:48:19+08:002019-04-20T02:48:19+08:00

    Sem usar awk muito :

    $ awk -v OFS="<" '{ print NR, $0 }' file | sort -t '<' -u -k2,2 | sort -t '<' -k1,1n | cut -d '<' -f 2-
    aaa<vvv>bbb<vvv>ccc
    xxx<vvv>yyy<vvv>zzz
    111<vvv>222<vvv>333
    

    Isso só serve awkpara inserir um número de linha seguido de <nos dados originais. Fazemos isso para poder acompanhar a ordenação das linhas originais. Usamos <como delimitador entre o número da linha e o resto da linha porque este também aparece como delimitador entre o primeiro campo original e o resto da linha.

    Após o primeiro estágio do pipeline, no qual awké usado para inserir os números das linhas, os dados ficarão como

    1<aaa<vvv>bbb<vvv>ccc
    2<xxx<vvv>yyy<vvv>zzz
    3<aaa<vvv>new<vvv>new2
    4<111<vvv>222<vvv>333
    

    A próxima etapa do pipeline classifica isso no segundo campo (o primeiro campo original), removendo duplicatas. O resultado será

    4<111<vvv>222<vvv>333
    1<aaa<vvv>bbb<vvv>ccc
    2<xxx<vvv>yyy<vvv>zzz
    

    O segundo sortrestaura a ordem de linha original ordenando as linhas no primeiro campo numericamente, e obtemos

    1<aaa<vvv>bbb<vvv>ccc
    2<xxx<vvv>yyy<vvv>zzz
    4<111<vvv>222<vvv>333
    

    O cutentão remove os números do primeiro campo (e o delimitador inserido).


    Uma solução que fornece saída ordenada sem usar awknada pareceria

    $ sort -t '<' -u -k1,1 file
    111<vvv>222<vvv>333
    aaa<vvv>bbb<vvv>ccc
    xxx<vvv>yyy<vvv>zzz
    

    Esta é essencialmente a segunda etapa no pipeline acima e classifica o arquivo no primeiro campo enquanto remove duplicatas.


    Uma awksolução seria como

    $ awk -F '<' '!seen[$1]++' file
    aaa<vvv>bbb<vvv>ccc
    xxx<vvv>yyy<vvv>zzz
    111<vvv>222<vvv>333
    

    Isso armazena o primeiro campo como uma chave em uma matriz associativa chamada seene pós-incrementa o valor associado. Se o valor na matriz para a chave fornecida for zero (ou seja, este primeiro campo não foi visto antes), a linha é impressa.

    • 2
  2. Cbhihe
    2019-04-21T00:25:33+08:002019-04-21T00:25:33+08:00

    Ou equivalentemente com nem awknem cut, mas com sed:

    $ sed '=' file \
          | sed 'N;s/\n/</' \
          | sort -t"<" -u -k2,2 \
          | sort -t"<" -k1,1 \
          | sed 's/^[0-9]*<//'
    aaa<vvv>bbb<vvv>ccc
    xxx<vvv>yyy<vvv>zzz
    111<vvv>222<vvv>333
    

    Mas isso é muito chato. A última solução do @Kusalananda (baseada em awk) é muito melhor.


    Apenas por uma questão de pedagogia, os dois primeiros sedblocos acima, são equivalentes ao cmd mais compacto de Kusalananda awk:

    • sed '=' file, imprime números de linha para pedidos futuros
    • sed 'N;s/\n/</', acrescenta a próxima linha de entrada no espaço do padrão (ou seja, "junta as linhas atual e seguinte") e substitui o final da linha \npor <.

    A 3ª e última seddica, sed 's/^[0-9]*<//', substitui o número da linha e o "<" colocado no início de cada linha, sem nada.


    Para obter mais detalhes sobre o sedproblema, $ info sedem seu console.

    • 0
  3. Rakesh Sharma
    2019-04-21T10:24:43+08:002019-04-21T10:24:43+08:00

    Usando GNU sed, podemos fazer a tarefa como dada:

    $ sed -Ene '
       G
       /^([^<]+)<vvv>.*\n\1(\n|$)/d
       P;s/<vvv>.*//;H
     ' input.txt
    

    Armazene o primeiro campo no espaço de espera e compare-o com o primeiro campo da linha atual. Somente quando forem diferentes, atualize a espera como também imprima a linha atual.

    • 0
  4. Praveen Kumar BS
    2019-04-23T08:29:47+08:002019-04-23T08:29:47+08:00

    Tentei com abaixo de 2 métodos

    Method1
    
     awk -F "<" '{if (!seen[$1]++)print }' filename
    
    Method2
    
    awk -F "<" '!a[$1]++' filename
    

    resultado

    aaa<vvv>bbb<vvv>ccc
    xxx<vvv>yyy<vvv>zzz
    111<vvv>222<vvv>333
    
    • 0

relate perguntas

  • Como posso melhorar este script de conversão de personagens?

  • Como remover uma única linha entre duas linhas

  • Reorganize as letras e compare duas palavras

  • Embaralhamento de arquivo de várias linhas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve