
Estoy buscando obtener todas las líneas que tienen la palabra 'cadena_búsqueda' + la línea después + la línea que coincide con 'mod' antes.
Lo intenté:
grep -n 'mod\|search_string' ip | grep --before 1 search_string> inter
grep -n --after 1 search_string ip >> inter
sort -t':' -k1,1n -u inter -o op
¿Existe una mejor manera?
Archivo:
mod start1
some lines
mod start2
other lines
mod start3
many other lines
search_string yada yada
hello
many other lines
search_string yada yada
bye
mod start4
search_string baba baba
this too
mod start5
Rendimiento esperado :
mod start3
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too
Respuesta1
awk '
$0 ~ /mod/ { md=$0 }
$0 ~ /search_string/ { if(md!="") { print md }; md="" ; print; getline; print }
'
Explicación:
- Una línea que contiene
mod
se guarda comomd
. - Una línea que contiene
search_string
activadores que imprimen lo guardado previamentemd
, la línea en sí y la línea siguiente. if(md!="")
ymd=""
están ahí para asegurarse de que no obtengamod
líneas duplicadas cuando haya muchassearch_string
-s debajo de una solamod
(mod start3
en su ejemplo).
Nota:
- Una línea que contenga ambos
mod
ysearch_string
romperá esta lógica.
Respuesta2
Su archivo contiene caracteres de "retorno de carro". Es mejor eliminarlos en Unix. Para imprimir lo que imprime la secuencia de comandos que publicó (sin retornos de carro), intente:
awk '{gsub(/\r/,"")}
/mod/ { a = $0 }
/search_string/{ if(a!=""){print(a);a=""}
print;getline;print
}
' infile
O como una sola línea:
$ awk '{gsub(/\r/,"")}/mod/{a=$0}/search_string/{if(a!=""){print(a);a=""}print;getline;print}' infile
mod start3
search_string yada yada
hello
search_string yada yada
bye
mod start4
search_string baba baba
this too
Como es posible utilizar un separador de registros de varios caracteres en (GNU) awk, podemos configurar el separador de registros mod
e imprimir solo los registros que contengan search_string
. Se requiere printf para reconstruir el registro original.
Para imprimir lo que publicó como "Resultado esperado", intente:
awk '/search_string/{printf("mod%s", $0)}' RS=mod infile
Respuesta3
Si quieres esto en un script de Python:
# Read file into memory.
with open('myfile.txt') as f:
lines = [line.rstrip() for line in f]
# Loops through lines backwards, looking for string and optionally mod.
output_lines = list()
find_mod = False
for i, line in enumerate(lines[::-1]):
if 'search_string' in line:
output_lines.append(lines[::-1][i-1])
output_lines.append(lines[::-1][i])
find_mod = True
elif find_mod and 'mod' in line:
output_lines.append(lines[::-1][i])
find_mod=False
print("\n".join(output_lines[::-1]))