Tengo el archivo:
DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
***** SPAM RECHAZADO ***** Mail Delivery (failure)
Mail Delivery (failure)
"Today" show ST0CK-NEWS
***** SPAM RECHAZADO ***** Juega Gratis la Lotto con mas de 130 millones
Juega Gratis la Lotto con mas de 130 millones
y usando comandos de unix me gustaria retirarle todas las lineas que
tengan las palabras "SPAM RECHAZADO" y la linea siguiente a ellas de
forma que quedara asi:
DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
"Today" show ST0CK-NEWS
Por cierto ya lo intente con grep -v -A 1 pero no funciono.
--
Red-Handed un programa de radio para informaticos
http://www.red-handed.com.ar
Te ayudo con una parte del problema, con esta expresión regular
capturas la línea donde sale "spam rechazado":
/^\*\*\*\*\* SPAM RECHAZADO \*\*\*\*\*.+$/
Ahora bien, para capturar la inmediatamente siguiente y además
borrarla, te sugiero que hagas un programita en algún lenguaje de
scripting. O si hay algún mago de sed que nos de una mano, sería la
herramienta indicada para el trabajo, pero no la domino.
-Óscar.
Hombre, pues esto saca una respuesta como la que quiere, pero no creo
que sirva mucho por que si el texto tiene mas lineas no las muestra,
pero espero le sirva de pista para resolver su inquietud:
$: sed -n -e '/SPAM/{$p;g;$!p;g}' -e h spam.txt
DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
"Today" show ST0CK-NEWS
$:
No conozco "sed" lo suficiente, por intuición me parece que debería
servir para lograr el tipo de filtrado que quieres. En su defecto, te
propongo este script de ruby, ponlo en el archivo "clean.rb" y
ejecútalo así: "ruby clean.rb <inputFile> <outputFile>".
--
#!/usr/local/bin/ruby
if (ARGV.length() != 2)
print "Usage: ruby clean.rb <inputFile> <outputFile>"
exit
end
nextLine = nil
out = File.new(ARGV[1], "w")
reject = /^\*\*\*\*\* SPAM RECHAZADO \*\*\*\*\* (.+)$/
IO.foreach(ARGV[0]) { | line |
if (reject.match(line) || line.strip() == nextLine)
nextLine = $1
else
out.puts(line)
end
}
out.close()
Hola Óscar.
primero hice este script:
cat archivo | sed -e 'N' -e '/.*\*\*\*\*\*.*\n.*/d' > /tmp/tmp
head -n 1 /tmp/tmp
tail +2 /tmp/tmp | sed -e 'N' -e '/.*\*\*\*\*\*.*\n.*/d' | sed '/^$/d'
rm /tmp/tmp
pero no me gusto lo de crear un archivo que voy a borrar 3 lineas mas
abajo, asi que hice una segunda version que ademas solo usa sed:
cat archivo | sed -e 'N' -e '/.*\*\*\*\*\*.*\n.*/d' | sed -e '1p' -e
'1d' -e 'N' -e '/.*\*\*\*\*\*.*\n.*/d' | sed '/^$/d'
La "magia" esta en comando 'N' que permite añadir una linea mas al
pattern space y con eso no trabajar linea por linea sino de dos en
dos, de forma que si este fuera el archivo con el numero de cada
linea:
1 DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
2 ***** SPAM RECHAZADO ***** Mail Delivery (failure)
3 Mail Delivery (failure)
4 "Today" show ST0CK-NEWS
5 ***** SPAM RECHAZADO ***** Juega Gratis la Lotto con mas de 130 millones
6 Juega Gratis la Lotto con mas de 130 millones
sed se ejecutaria con un pattern space de 1,2 luego 3,4 y por ultimo
5,6. Con la expresion '/.*\*\*\*\*\*.*\n.*/d' se borran los pattern
space que comienzan en un numero impar, en este caso 5,6
y el texto quedaria asi:
1 DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
2 ***** SPAM RECHAZADO ***** Mail Delivery (failure)
3 Mail Delivery (failure)
4 "Today" show ST0CK-NEWS
El siguiente paso es borrar los pattern space que comiencen con numero
par, para eso llamo de nuevo a sed y con las expresiones '1p' y '1d'
le digo que ignore la primera linea y empieze en la segunda(par)
nuevamente selecciono de a dos lineas con el comando'N' y esto crea
los pattern space 2-3, 4-linea vacia, al aplicar de nuevo la
expresion '/.*\*\*\*\*\*.*\n.*/d' se elimina el pattern space 2-3 y
texto queda asi:
1 DON'T DELETE THIS MESSAGE -- FOLDER INTERNAL DATA
2 "Today" show ST0CK-NEWS
3
por ultimo para borrar la linea en blanco que sobro del pattern space
4-linea vacia, llamo a sed con la expresion '/^$/d'
La explicacion que lei del comando 'N' fue del Sed Tutorial[1] de
Donovan Rebbechi seccion Pattern Matching Across More than 1 Line
Ademas luego de terminar encontre en el Sed FAQ un script para
responder a la pregunta: How do I delete or change a block of text if
the block contains a certain regular expression?[2], pero todavia no
he dado con la manera de hacerlo funcionar.
[1] http://pegasus.rutgers.edu/~elflord/unix/sed.html
[2] http://sed.sourceforge.net/sedfaq4.html#s4.21
> -Óscar.
Gracias por compartir la solución es un habito que aveces se pierde o
ni se adquiere.
2006/9/18, Camilo <camilo...@gmail.com>:
--
ATT: Fredy P.
es.wikipedia.org - La mejor enciclopedia del mundo!
Suerte and F.S.Fv.
_________________________________________________________________________
F.S.Fv. es acronimo de Free Software Forever
En parte es para responder la pregunta y que la reputacion de sl-prog
quede intacta, por otro lado estoy seguro que si en un mes miro algo
como:
cat archivo | sed -e 'N' -e '/.*\*\*\*\*\*.*\n.*/d' | sed -e '1p' -e
'1d' -e 'N' -e '/.*\*\*\*\*\*.*\n.*/d' | sed '/^$/d'
no voy a entender absolutamente nada, asi que de paso aprovecho la
lista para documentar ese script y saber que hacer la proxima vez que
lo necesite o a sed,
ademas todavia no entiendo el script de Anthony y no queria que a los
demas les pasara lo mismo cuando enviara el mio.
Por ultimo me gustaria añadir que a diferencia de otras listas de
correo donde solo se trata de preguntar y responder yo veo a esta como
un espacio donde aprender en comunidad.