Reorganizar conteúdo de um arquivo

0

Eu gostaria de reorganizar o conteúdo de um arquivo por linha (veja abaixo), idealmente sem usar Perl ou Python (eu não tenho permissão para ... não pergunte).

O arquivo de entrada contém linhas de cabeçalho e linhas não ordenadas com resultados de operação de backup. Os arquivos de saída devem conter as linhas ordenadas conforme mostrado abaixo.

Arquivo original:

Completed Backups
Backups with Warnings
Failed Backups
Server A backup was completed with warnings
Server B backup was successful
Server C backup failed
Server D backup was completed with warnings

Resultado final:

Completed Backups
Server B backup was successful
Backups with Warnings
Server A backup was completed with warnings
Server D backup was completed with warnings
Failed Backups
Server C backup failed
VikJES
fonte
Não está claro em tudo com base em qual chave você deseja organizar as linhas. Por favor descreva. O exemplo que você fornece é o conteúdo real do arquivo ou a descrição do conteúdo. Se é apenas uma descrição, como é o conteúdo? O que você já tentou?
pabouk
Me desculpe, mas eu não sei o que você quer dizer com "chave" ... Este é o conteúdo real (ou muito próximo) do arquivo. As primeiras 3 linhas estão sempre no começo do arquivo. Gostaria que todas as linhas de backups bem-sucedidas fossem listadas na linha "Backups concluídos" no início e as linhas "concluídas com aviso" fossem listadas em "Backup com avisos" e assim por diante. Eu não tentei muito porque eu não tenho absolutamente nenhuma idéia de como fazer isso, no começo, eu pensei que o sed pudesse fazer isso, mas eu não consigo entender.
VikJES

Respostas:

1

Abuso mal-intencionado de grep ahoy. Meu script original baseou-se no fato de que o grep faz distinção entre maiúsculas e minúsculas e que seu texto é estranhamente encapsulado, e esses casos são exclusivos. Eu fiz uma segunda variante (você pode ver a antiga na trilha de edição), que usa um pedaço maior das linhas que você precisa reorganizar. Fazê-lo 'corretamente' provavelmente acabaria sendo mais rápido, já que ele é executado em todo o seu arquivo de texto para cada comando grep - para um arquivo grande, isso significa que ele passa por 6 ciclos para reorganizá-lo.

Isso deve funcionar com alguns pequenos mods no windows ou linux, ou simplesmente copiar colado. Isso pressupõe que seu arquivo de origem é chamado original.txt e sua saída é new.txt. Você provavelmente pode classificar as linhas grep se precisar delas em ordem alfabética. >> acrescenta a uma nova linha

 #! /bin/sh

    grep "Completed Backups" original.txt >> new.txt
    grep "backup was successful" original.txt >> new.txt
    grep "Backups with Warnings" original.txt >> new.txt
    grep "backup was completed with warnings" original.txt >> new.txt
    grep "Failed Backups"  original.txt >> new.txt
    grep "backup failed" original.txt >> new.txt

Eu provavelmente esperaria a resposta correta do sed ou do awk se eu fosse você. Eu também experimentaria subconjuntos maiores de suas strings

Geek do viajante
fonte
1

Infelizmente, sedou awknão vai ajudar muito aqui, porque a maneira mais fácil de reordenar as linhas é processar a entrada em várias passagens, como o Journeyman Geek mostrou.

Aqui está apenas uma alternativa ligeiramente diferente, que abre o arquivo de saída apenas uma vez. Outra abordagem é também nos cabeçalhos, aqui eles são recriados em vez de transferi-los da origem.

#!/bin/sh

output=new.txt
input=original.txt

{
  echo "Completed Backups"
  grep "Server .* backup was successful" < "$input"

  echo "Backups with Warnings"
  grep "Server .* backup was completed with warnings" < "$input"

  echo "Failed Backups"
  grep "Server .* backup failed" < "$input"
} > "$output"

Como alternativa para especificar a entrada e a saída no script, você pode lê-las a partir da linha de comando:

output="$1"
input="$2"
pabouk
fonte
apenas por curiosidade, como isso abre o arquivo de saída apenas uma vez? Eu acho que você pode ter perdido as linhas de 'título' também. Parece mais 'bom' bash do que a minha resposta XD
Journeyman Geek
O redirecionamento > "$output"no final é executado apenas uma vez e é válido para o bloco inteiro {... de }modo que o arquivo de saída é aberto apenas uma vez. Outra alternativa poderia ser colocar exec > "$output"para o começo. Em seu script, o arquivo de saída é aberto repetidamente com todos os redirecionamentos do stdout. --- Eu omiti as linhas de título intencionalmente: "eles são recriados em vez de transferidos da fonte"
pabouk
Ahh, entendi. Tipo de falta que por algum motivo
Journeyman Geek