2011-09-11 10 views
5

Necesito eliminar una línea coincidente y una anterior a ella. Por ejemplo, en el archivo a continuación tengo que eliminar las líneas 1 & 2.¿Cómo elimino una línea coincidente y la anterior?

Probé la página "grep -v -B 1". de. "1.txt y esperaba que no imprime las líneas matchning y el contexto.

Probé la How do I delete a matching line, the line above and the one below it, using sed? pero no pudieron entender el uso de sed.

---1.txt-- 
**document 1**       -> 1 
**page 1 of 2**      -> 2 

testoing 
testing 

super crap blah 

**document 1** 
**page 2 of 2** 
+2

try ['archivo tac | sed-e '/ foo /, + 1d' | tac'] (http://stackoverflow.com/a/31227307/2297751) – Jon

Respuesta

1

No muy familiarizado con sed, pero he aquí una expresión perl para hacer el truco:

cat FILE | perl -e '@a = <STDIN>; 
        for($i=0 ; $i <= $#a ; $i++) { 
        if($i > 0 && $a[$i] =~ /xxxx/) { 
         $a[$i] = ""; 
         $a[$i-1] = ""; 
        } 
        } print @a;' 

edición:

donde "xxxx" es lo estás tratando de unir

+0

esto tiene que almacenar primero el archivo completo ... –

+0

Y el uso inútil del gato debería ir. – tripleee

+0

Sí, ciertas piezas de esta solución pueden criticarse, pero el concepto general es sólido y el código de ejemplo lo implementa bastante bien. Es facil de entender Lo suficiente para comenzar a alguien. Y ese es todo el punto de una respuesta aquí. No necesita ser perfecto. Me gusta esta respuesta. Ciertamente me ayudó con un problema similar al de la pregunta original. – Keve

11

que quiere hacer algo muy similar a la answer given

sed -n ' 
/page . of ./ { #when pattern matches 
n #read the next line into the pattern space 
x #exchange the pattern and hold space 
d #skip the current contents of the pattern space (previous line) 
} 

x #for each line, exchange the pattern and hold space 
1d #skip the first line 
p #and print the contents of pattern space (previous line) 

$ { #on the last line 
x #exchange pattern and hold, pattern now contains last line read 
p #and print that 
}' 

Y como

sed -n '/page . of ./{n;x;d;};x;1d;p;${x;p;}' 1.txt 
+0

Tenga en cuenta que puede hacerlo en una línea: 'sed -n '/ página 1/{n; x; d;}; x; 1d; $ G; p' 1.txt' – Beta

+0

@Beta: Por supuesto, la las líneas adicionales, etc. son simplemente una anotación – Hasturkun

+1

¿Por qué se bajó este valor? hace lo que quería la pregunta asker (y está en sed para arrancar) – Hasturkun

2

grep -v -B1 no funciona porque va a saltar esas líneas, pero incluirá posteriormente en una sola línea (debido al -B1. Para verificar esto, pruebe el comando en:

**document 1**       -> 1 
**page 1 of 2**      -> 2 

**document 1** 
**page 2 of 2** 
**page 3 of 2** 

Notará que la línea page 2 se omitirá porque esa línea no coincidirá y la siguiente como no coincidirá.

Hay una solución sencilla awk:

awk '!/page.*of.*/ { if (m) print buf; buf=$0; m=1} /page.*of.*/ {m=0}' 1.txt 

El comando awk dice lo siguiente:

Si la línea actual tiene que "... la página de", entonces será la señal de que usted no ha' Encontré una línea válida. Si no encuentra esa cadena, imprima la línea anterior (almacenada en buf) y restablezca el búfer en la línea actual (por lo tanto forzándolo a latencia 1)

1
grep -vf <(grep -B1 "page.*of" file | sed '/^--$/d') file 
+0

Desea agregar una opción '-x' al' grep' externo. Esto no es terriblemente eficiente. – tripleee

Cuestiones relacionadas