Quiero eliminar dos líneas consecutivas específicas que coincidan con patrones de una línea específica de un archivo.
Por ejemplo, el contenido del archivo es el siguiente.
Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5: xyz
Line6: Name: 456
Line7: abc
Quiero encontrar las líneas que comienzan desde la línea 4, que coincidan con el patrón de la primera línea que comienza con "Nombre:" y que coincidan con el patrón de la segunda línea que comienza con espacios en blanco y eliminar las dos líneas consecutivas.
¿Alguna forma eficiente de hacer esto usando Shell sed
o algo más?
Para ser un poco más claro, quiero eliminar la información de firma/suma de verificación de MANIFEST.MF.
Ejemplo de MANIFEST.MF como se muestra a continuación: Del siguiente archivo de manifiesto, quiero eliminar la entrada "Nombre:". donde la entrada "Nombre:" puede estar en una línea o en 2 (o más) líneas.
Inicialmente, mi solución fue buscar la primera entrada "Nombre:" seguida de la entrada "SHA-256-Digest:" y eliminarla hasta el final del archivo. Desafortunadamente, esta solución tiene el problema de eliminar una entrada necesaria en el medio. Por ejemplo, "NetBeans-Simply-Convertible:" también se eliminará.
Entonces, ahora quiero eliminar la entrada "Nombre:" si está disponible en 1 línea o la entrada abarca 2 o más líneas. Pero no debería perder entradas como "NetBeans-Simply-Convertible:" mientras elimino las entradas "Nombre:".
Ya estoy eliminando las entradas "SHA-256-Digest:" con el siguiente comando archivado consed -i "/^\SHA-256-Digest: /d" $manifest_file
Manifest-Version: 1.0
Version-Info: ....
Name: com/abc/xyz/pqr/client/relationship/message/notifier/Relati
onshipUpdateNotifierFactory.class
SHA-256-Digest: cSSyk6Y2L2F9N6FPtswUkxjF2kelMkGe4bFprcQ+3uY=
Name: com/abc/xyz/pqr/client/relationship/ui/BaseRelationshipView
$5.class
SHA-256-Digest: w9HgRjDuP024U4CyxeKPYFe6rzuzxZF3b+9LVG36XP8=
Name: com/abc/xyz/pqr/client/impl/MofRelationshipAgentImpl.class
SHA-256-Digest: GwIBIU+UdPtjyRhayAVM90Eo+SwCT/kP65dI59adEnM=
Name: com/abc/xyz/pqr/client/settings/ConvertibleProperties.class
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
vertibleProperties
SHA-256-Digest: 5FszAtfpPXcLx/6FBWbfeg6E4fwFMRozV+Q+3rReATc= ...
Rendimiento esperado:
Manifest-Version: 1.0
Version-Info: ....
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
vertibleProperties
...
Respuesta1
awkacercarse:
Digamos que tenemos el siguiente archivo de entrada file.txt
(considerando que cada línea contiene Line<number>:
como primer campo):
Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5: xyz
Line6: Name: 456
Line7: abc
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11: abc
Line12: Name: 333
Line13: ccc
awk '{ if ($2 == "Name:") {
if ((getline l) > 0){
if (l ~ /^\S+ \S+/) { next } else { print $0 RS l }
}
} else { print }
}' file.txt
La salida:
Line1: a
Line2: b
Line3: c
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11: abc
'var getline'- lee el siguiente registro de la entrada de awk en la variablevar
Elobtener líneaEl comando devuelve 1 si encuentra un registro y 0 si encuentra el final del archivo.
Respuesta2
Ves que no está claro lo que preguntas: una respuesta borra 4 líneas (las dos coincidentes y las dos siguientes); otro borra todoperolas líneas coincidentes...
Agregaré lo que entiendo que quieres: borro 2 líneas, la que coincide Name: 123
y la siguiente. Hago esto con sed
:
sed -e '/Name: 123/{N;d}' filename
Respuesta3
Usando ed
:
$ printf '%s\n' 'g/^ / s///\' '-,.j' 'g/^Name: /d' 'g/SHA-256-Digest: /d' '4,$g/^$/d' ,p Q | ed -s file
Manifest-Version: 1.0
Version-Info: ....
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}ConvertibleProperties
Esto aplica el siguiente script de edición a su archivo de entrada:
g/^ / s///\
-,.j
g/^Name: /d
g/SHA-256-Digest: /d
4,$g/^$/d
,p
Q
Consta de seis comandos separados:
Los dos comandos
s///
se-,. j
aplican a cada línea que comienza con un carácter de espacio. La expresión regular vacía en els
comando reutiliza la expresión^
delg
comando anterior (que se usa para aplicar uno o más comandos a líneas que coinciden con una expresión regular), por lo que els
comando elimina el primer espacio vacío en las líneas que comienzan con espacios vacíos. Luego, elj
comando une la línea modificada con la línea anterior. Esto efectivamente deshace el ajuste de las líneas en los datos de entrada.El comando
d
se aplica a todas las líneas que comienzan conName:
, eliminándolas.Del mismo modo,
SHA-256-Digest:
se eliminan las líneas que comienzan con.Las líneas vacías se eliminan desde la línea 4 en adelante.
Enviamos el búfer completo a la salida estándar para mostrar el resultado.
Q
sale del editor incondicionalmente (puede utilizarlowq
para escribir los cambios en el archivo original).
Respuesta4
sed -e '
4,$!d; # skip non-relevant portion
/Name:/N; # grab the line coming after Name:
/\n.* /d; # what we were after is not this
P;D
' yourfile