sed

sed

Tengo un archivo como:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,

Necesito mantener las líneas con marca de tiempo, es decir, 171023 03014426 1234 XXXX XXXXXXXXmantenerlas error code: 123desde las otras líneas, es decir, desde el inicio de la línea hasta la coma, y ​​escribir los cambios en el mismo archivo.

Producción:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

¿Cómo puedo hacer eso?

Respuesta1

Según entiendo tu pregunta, quieres esto.

171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,

para convertirse en esto:

171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Hay muchas maneras de hacer esto, así que elija el método que desee/le guste/prefiera.

sed

$ sed 's/\(error code:[[:blank:]][[:digit:]]*\),.*/\1/' input.txt                                     
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Si desea realizar cambios en el archivo original input.txt, utilice sed -ien lugar de simplementesed

awk

$ awk -F ',' '/^error code/{$0=$1};1' input.txt                                                       
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Este enfoque hace que la coma se trate como un separador de columnas (en awk-speak "campo"), por lo que aquí básicamente encontramos una línea que comienza con error codetexto y reemplazamos la línea original con solo una columna $1, que en su caso es todo lo que está antes de la coma, es decir error code: 123.

awkNo puedo editar el texto (la mayoría de las versiones), sed -ipero siempre puedes enviar cosas a un archivo nuevo y reemplazar el archivo antiguo con uno nuevo, como:

awk -F ',' '/^error code/{$0=$1};1' input.txt > new_data.txt && mv new_data.txt input.txt 

pura fiesta

#!/usr/bin/env bash

# make temp file for writing stuff
temp=$(mktemp)

# read input file, make necessary changes, write to temp file
while IFS= read -r line;
do
    case $line in
        "error code:"*) printf "%s\n" "${line%%,*}" >> "$temp";;
        *) printf "%s\n" "$line" >> "$temp";;
    esac
done < "$1"
mv  "$temp" "$1"

Prueba de funcionamiento:

$ # before 
$ cat input.txt                                                                                       
171023 03014426 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
171023 03110749 1234 XXXX XXXXXXXX
error code: 123, pc=546, call=0,
$ # after
$ ./edit_error_codes.sh input.txt                                                                     
$ cat input.txt
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123

Respuesta2

Si las líneas que no quieres tocar no tienen comas y siempre quieres eliminar solo la primera coma y todo lo que sigue, puedes usar una expresión muy simple.

$ sed 's/,.*//' file
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123
  • s/old/new/reemplazar oldconnew
  • .*cualquier número de cualquier carácter

Para editar el archivo en el lugar, use sedla opción en el lugar, que es -i. Si se agrega un sufijo para el archivo de respaldo después de -i, automáticamente escribe una copia de seguridad del archivo original con esa extensión en el mismo directorio, por ejemplo

sed -i 's/,.*//' file

sobrescribe filecon la secuencia modificada, pero

sed -i.orig 's/,.*//' file

escribe la secuencia modificada filey escribe un nuevo archivo file.origcon el contenido original.

Respuesta3

Puedes usar un cutcomando simple para hacer lo que quieras.

cut -d"," -f1 input.txt

Escríbalo nuevamente en el mismo archivo.

cut -d"," -f1 input.txt | tee input.txt

información relacionada