Sed regex - inclui correspondência original

0

ENTRADA:

dsfgsdf8gfsd
2011.06.26. v
iudsfg98sdfg
sosdufgsdfg
2011.06.27. h
8xdofguiosdfg
jdasfhasd89fa
2011.06.28. k
ydsfgsdgsdg
dsfgdsfzfszgh
2011.06.29. sze
ds9fgisdfgsdfg
asdfasdfasddf
2011.06.30. cs
dsg789sdiofgsdg
dsfig89dsfgds
2011.07.01. p
sd9fg8sdgsdg
sdlfjgsd89öfgxcbv
dsglsd9gcxbv
dsflgjsdlfgfsdg
sdfsdfgdxfgxc
2011.07.02. szo
cvbdsgfsd
2011.07.03. v
dfgsdfgsd
2011.07.04. h
sdfgsdfgsdg

Como posso obter essa OUTPUT com, por exemplo, sed? (ou Perl?)

2011.06.26. v
iudsfg98sdfg
sosdufgsdfg
----------
2011.06.27. h
8xdofguiosdfg
jdasfhasd89fa
----------
2011.06.28. k
ydsfgsdgsdg
dsfgdsfzfszgh
----------
2011.06.29. sze
ds9fgisdfgsdfg
asdfasdfasddf
----------
2011.06.30. cs
dsg789sdiofgsdg
dsfig89dsfgds
----------
2011.07.01. p
sd9fg8sdgsdg
sdlfjgsd89öfgxcbv
dsglsd9gcxbv
dsflgjsdlfgfsdg
sdfsdfgdxfgxc
----------
2011.07.02. szo
cvbdsgfsd
----------
2011.07.03. v
dfgsdfgsd
----------
2011.07.04. h
sdfgsdfgsdg

Então eu quero trocar o:

2011.06.26. v

AND

2011.06.27. h

para isso:

----------
2011.06.26. v

AND

----------
2011.06.27. h

Eu já tentei (não ri: D):

sed "s/[0-9]\{4\}\.[0-9]\{2\}\.[0-9]\{2\}\. /WTF/g"

Mas eu não sei como combinar "h, k, sze, cs, p, szo, v" em sed, e eu não sei como eu posso colocar as coisas correspondentes no "WTF" (em ... / WTF / g ")

Alguém tem alguma ideia? : \

Obrigado!

    
por LanceBaynes 10.06.2011 / 20:36

4 respostas

2

Um ponto de partida é esta linha sed:

$ echo 2011.06.26. v | sed 's/^\([0-9]\+\.[0-9]\+\.[0-9]\+\. \([hv]\|sze\)\)$/----------\n/'
----------
2011.06.26. v

Como o sed usa a sintaxe básica de expressão regular (por padrão), você precisa escapar dos caracteres ()|+ para obter seu significado especial (agrupamento, alternativa, um ou mais). Com você retrocedeu a primeira partida do grupo.

    
por 10.06.2011 / 21:10
0

Eu encontrei esta solução usando sed :

sed -n '/^[0-9]\{4\}\.[01][0-9]\.[0123][0-9]\./,${:a;N;$!ba;{s/\([0-9]\{4\}\.[01][0-9]\.[0123][0-9]\.\)/--------------\n/g;p}}'

A desvantagem é que a data precisa ser correspondida duas vezes. Talvez haja outra (melhor) solução. A saída é exatamente como você espera no seu exemplo.

    
por 10.06.2011 / 21:46
0

Em outras palavras, você deseja inserir a linha ---------- antes de cada linha que contém uma data YYYY.MM.DD seguida por um espaço e várias letras minúsculas. Existem várias maneiras de fazer isso. Você pode usar o comando insert ( i ):

sed -e '/^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9] [a-z][a-z]*$/ i \
----------'

Ou você pode substituir a string vazia no começo da linha por uma nova linha.

sed -e '/^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9] [a-z][a-z]*$/ s/^/----------\
'

Ou você pode usar & no texto de substituição de um comando s para representar o padrão correspondente.

sed -e 's/^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9] [a-z][a-z]*$/----------\
&'

Algumas implementações sed permitem que você escreva \n em vez de barra invertida-nova linha no texto de substituição, mas em outros \n imprime \n ou n .

    
por 10.06.2011 / 22:22
0

Você deve usar o awk

awk ' /[0-9]{4}\.[0-9]{2}\.[0-9]{2}\. / { print "---------------------\n" $0 ; continue } /^/ { print $0 } ' <"INPUTFILE" >"OUTPUTFILE"

basicamente funciona em 2 etapas:

passo 1: /[0-9]{4}\.[0-9]{2}\.[0-9]{2}\. / { print "---------------------\n" $0 ; continue }

significa: se ele usa /4digits.2digits.2digits. / em seguida, imprima "---...-- \ n" seguido pela linha correspondente e dê um loop na linha seguinte (= "continue").

step2: /^/ { print $0 }

significa: se não correspondermos ao acima, então para todas as outras linhas (ou seja, combinando um começo de linha, então até mesmo uma linha vazia será correspondida), basta imprimir essa linha.

    
por 06.12.2012 / 18:55

Tags