Melhor maneira de executar uma série de sete comandos idênticos em sed? [duplicado]

2

Na postagem Sed - Substitua as primeiras k ocorrências de uma palavra em um arquivo , um usuário sugere:

sed 's/old/new/;s/old/new/;s/old/new/;s/old/new/;s/old/new/' filename

como um método de substituir as primeiras k instâncias de uma palavra em uma linha. Parece uma solução deselegante para o problema de substituir as primeiras k instâncias do antigo pelo novo. Existem outros métodos discutidos para fazer outras coisas. Mas não há outras (ou nenhuma outra solução elegante) para o problema de substituir as primeiras k ocorrências de uma palavra em uma linha usando sed.

tl / dr:

Eu tenho um grande grupo de itens que eu chamo de "slugs" que são realmente úteis para uma variedade de pequenas coisas estranhas que eu quero acompanhar. Eles se parecem com isso:

#slug YYYY/MM/DD d hhmm field1 field2 field3 notes

E eu os mantenho em uma série de arquivos que são datados. Então eu coloquei os arquivos através de um grep | sed | cadeia do awk para gerar relatórios a partir dos dados. Então vamos dizer que o cachorro do meu vizinho está latindo e isso está me mantendo acordado à noite. Toda vez que eu ouço o latido do cachorro eu vou escrever o tempo, e depois vou anotar no meu arquivo de log.

#bark 2016/04/06 W 0214 0232 Police showed up!

Depois de um tempo, vou ter um banco de dados armazenado, e espero notar alguma tendência, como ... quem sabe o que ... os cachorros latem na lua cheia ou algo assim. A cadeia de pequenos programas seria semelhante:

grep "^#[Bb][Aa]" 2014* 2015* 2016* |\
sed 's/ /|/;s/ /|/;s/ /|/;s/ /|/;s/ /|/' |\
awk {something or other} >\
barking-dog-report

Então, meu problema é a parte sed:

sed 's/ /|/;s/ /|/;s/ /|/;s/ /|/;s/ /|/'

Que se traduz aqui em "substituir os primeiros cinco espaços em tubos." Eu uso o tubo como o separador de campo no awk. Um comando como s/ /|/5 não funciona, apenas altera o quinto espaço em cada linha para um pipe. Eu só acho que essa série de comandos sed parece ridícula. Não é uma substituição global s/ /|/g , porque quero manter os espaços como espaços (e não usá-los como separadores de campo) para a seção de anotações.

    
por Oswald Roswell 07.04.2016 / 07:59

1 resposta

1

Você pode combinar os cinco comandos sed em um (mas isso não diminui a duração):

sed 's/^\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \(.*\)/|||||/'

Mas você pode colocar a pesquisa grep no script sed para reduzir os comandos do shell em um (aqui com seus comandos de substituição originais):

sed -n '/^#[Aa][Bb]/{s/ /|/;s/ /|/;s/ /|/;s/ /|/;s/ /|/;p;}' files |\
awk '...' > report
    
por 07.04.2016 / 08:25

Tags