Tipo de script de shell

0

Estou tentando classificar um arquivo pequeno com algumas entradas contendo duas palavras, mas quero classificá-lo como uma entrada.

por exemplo, considere esta pequena lista

 peter barker painter
 carl baker cook
 joshua carpenter

Estes são todos os nomes e ocupações. Agora, digamos que eu queira usar a classificação para classificar essas entradas.

O problema é classificar usa espaços em branco como campos Então, se eu ordenar -k 1n eu vou classificar pelo primeiro nome

Mas eu quero classificar pelo nome completo e depois ter a opção de classificar por ocupação também. Como você pode ver algumas entradas não tem um nome completo, joshua só tem seu primeiro nome e sua ocupação. Então, para ele eu quero classificar apenas pelo primeiro nome, mas pelo nome completo dos outros.

Isso pode ser alcançado?

    
por mrmagin 23.11.2018 / 16:42

1 resposta

1

Supondo que seja apenas o sobrenome que está faltando (e não o primeiro nome) e que as palavras no arquivo não incluam espaços (o que tornaria extremamente difícil) Primeiro, leve os dados para o formato delimitado por tabulações com os nomes ausentes que foram substituídos por campos vazios:

$ awk -v OFS='\t' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file
peter   barker  painter
carl    baker   cook
joshua          carpenter

O script awk detectará linhas que contenham dois ou três campos. Ele simplesmente reformatará as linhas que já possuem três campos em três campos delimitados por tabulações enquanto move o segundo campo para o terceiro campo para as linhas que originalmente continham apenas dois campos.

Em seguida, classifique os dados com guias como delimitadores:

$ awk -v OFS='\t' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t $'\t' -k1,2 -k3
carl    baker   cook
joshua          carpenter
peter   barker  painter

A ordenação feita aqui é sobre o nome completo (campos um e dois) e depois por ocupação. Presume-se que você esteja usando um shell como bash que entende $'\t' como um caractere de tabulação.

Em vez de guias, você pode usar qualquer outro caractere que não interfira nos dados (aqui : ):

$ awk -v OFS=':' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t ':' -k1,2 -k3
carl:baker:cook
joshua::carpenter
peter:barker:painter

Em seguida, substitua o caractere delimitador escolhido, passando o resultado por tr (aqui substituindo por tabulações, porque ele fica bem):

$ awk -v OFS=':' 'NF == 3 { $1 = $1 } NF == 2 { $3 = $2; $2 = "" } { print }' <file | sort -t ':' -k1,2 -k3 | tr ':' '\t'
carl    baker   cook
joshua          carpenter
peter   barker  painter
    
por 23.11.2018 / 16:50