Estoy buscando una manera de hacer lo siguiente con un archivo delimitado por barras verticales en UNIX, para CADA LÍNEA y no estoy seguro de por dónde empezar:
- Busque un carácter en una línea de texto (¿se supone que usa GREP?)
- Si lo encuentra, agregue algo de texto al final de esa línea (¿usando SED?)
- Si no lo encuentra, busque otro carácter en la misma línea.
- Si lo encuentra, agregue texto al final de la línea; de lo contrario, no haga nada.
- BUCLE PARA TODAS LAS LÍNEAS DEL ARCHIVO
Cualquier indicador sería apreciada.
Respuesta1
Todo esto es sed
trabajo, no necesitas herramientas adicionales:
Supongamos que desea agregar foo
al final de la línea que contiene un f
y bar
al final de las líneas sin f
pero con unb
sed '/f/{
s/$/foo/
b
}
/b/s/$/bar/'
Puede "direccionar" líneas con /pattern/
, por lo que los siguientes comandos solo se ejecutan si contienen el patrón. Entonces, en el ejemplo, solo las líneas que contienen un f
desencadenan la ejecución del s
reemplazo y b
(el {}
grupo de comandos, por lo que todo lo que está dentro solo se aplica si la dirección coincide. Las b
ramas hasta el final del script para evitar agregar otra cadena para un coincidente b
.
Enfoque diferente sin rama:
sed '/f/s/$/foo/;s/^[^f]*b[^f]*$/&bar/'
Como ejercicio, puedes resolverlo tú mismo con algunos sed
conocimientos, utilizándolo man sed
si es necesario.
Respuesta2
Si desea agregar la misma cadena de texto al final de la línea para ambos escenarios (caracteres a buscar: 'X' 'Y'), puede hacerlo de la siguiente manera:
sed -e 's/[XY].*/&__ADDEDTEXT__/' yourfile
Por otro lado, si desea colocar textos separados al final de las líneas dependiendo del carácter, entonces puede hacer:
sed -e '
/X/s/$/__TEXT1__/; t
/Y/s/$/__TEXT2__/
' yourfile
Donde utilizamos el t
comando (leer como prueba) para detectar si el s///
comando anterior fue exitoso y saltar al final del código sed en la línea actual. Además, tenga en cuenta la sintaxis: /regex/s/// => si una línea comprende la expresión regular, realice la sustitución en la línea.
Respuesta3
Perl también es una herramienta útil que puede hacer todo de una sola vez.
Entonces, con el ejemplo de @Philippos, un programa Perl se vería así (parte de la sintaxis es opcional y se agregó para aclarar):
perl -pe '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
Esto lee file
y genera el resultado. También puedes "editar" el archivo en su lugar usando -pi -e
en lugar de -pe
( -i
significa "en su lugar"), así:
perl -pi -e '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
Probablemente también haya una manera de hacer esto, awk
aunque las pruebas iniciales fallaron (no soy tan competente en AWK), con Ruby (que se ve casi igual, envíame un mensaje si quieres ejemplos) y puede ser divertido en Bash puro.