Encontre uma coluna duplicada e separe-as em um arquivo ou variável (Bash)

1

Eu tenho como saída; (As colunas separadas por aba \t )

name1   something1
name1   something2
name1   something3
name2   something4
name2   something5

Para esta saída eu preciso de duas saídas (se houver name3 , precisarei de 3 saídas) como

name1   something1
name1   something2
name1   something3

e

name2   something4
name2   something5

Acho que isso será feito pelo AWK, mas não consegui criar palavras mágicas.

Qual é a melhor maneira de fazer isso?

Eu preciso de uma condição para ler $1 "1.coluna" e imprimir todos eles (não excluir duplicatas) a menos que ela mude e imprima outras colunas ($ 2, $ 3, ...)

Eu acho que usando loop ele imprime a primeira saída e assim por diante.

    
por makgun 11.08.2015 / 23:32

2 respostas

2

Tente isto:

awk -F'\t' '{print>$1;}' file

Quando o comando acima estiver completo, haverá mais dois arquivos no diretório:

$ cat name1
name1   something1
name1   something2
name1   something3
$ cat name2
name2   something4
name2   something5

Como funciona

  • -F'\t'

    Isto diz ao awk para usar um separador como o separador de campos.

  • print>$1

    Isto diz ao awk para imprimir cada linha para o arquivo nomeado após o primeiro campo.

Removendo caracteres ilegais dos nomes de arquivos

Suponha que o arquivo de entrada se pareça com:

$ cat file
name/1  something1
name/1  something2
name/1  something3
name/2  something4
name/2  something5

O código a seguir cria arquivos com base no campo de nome, mas com / removido:

awk -F'\t' '{name=$1; gsub(/[/]/, "", name); print>name;}' file

O acima foi testado no GNU awk e foi executado com sucesso. Se o seu awk não aceitar, tente:

awk -F'\t' '{name=$1; gsub("/", "", name); print>name;}' file

ou:

awk -F'\t' '{name=$1; gsub(/\//, "", name); print>name;}' file
    
por 11.08.2015 / 23:47
0

Acho que isso deve funcionar:

mkdir tmp; cd tmp
while IFS= read line; do
    echo "$line" >> $(echo "$line" | awk '{print $1}')
done
cat *

Isto lê a entrada linha por linha e acrescenta cada linha de acordo com o primeiro argumento.

Se você deseja transmitir para variável:

while IFS= read line; do
    key="$(echo "$line" | awk '{print $1}')"
    eval "INPUT_$key='\$INPUT_$key\$line'"
done

Se você tem grandes demandas, use:

#!/usr/bin/python

import sys
import re

for line in sys.stdin:
    f = open(re.split("\s+", line, 1), 'a')
    f.write(line)
    f.close()

Isso funcionará. Devo. Não pode falhar.

    
por 11.08.2015 / 23:39

Tags