sed

sed

Eu tenho um arquivo 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,

Preciso manter as linhas com timestamp, ou seja, 171023 03014426 1234 XXXX XXXXXXXXe manter error code: 123das outras linhas, ou seja, do início da linha até a vírgula, e escrever as alterações no mesmo arquivo.

Saída:

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

Como eu posso fazer isso?

Responder1

Pelo que entendi sua pergunta, você quer isso

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 se tornar isso:

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

Há muitas maneiras de fazer isso, então escolha o método que você deseja/gosta/prefere.

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

Se você quiser fazer alterações no arquivo original input.txt, use sed -iem vez de apenassed

estranho

$ 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

Essa abordagem faz com que a vírgula seja tratada como separador de coluna (em awk-speak "field"), então aqui basicamente encontramos a linha que começa com error codetexto e substituímos a linha original por apenas column $1, que no seu caso é tudo antes da vírgula, ou seja error code: 123.

awknão é possível fazer edição de texto (na maioria das versões), sed -imas você sempre pode enviar coisas para um novo arquivo e substituir o arquivo antigo por um novo, como:

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

pura festa

#!/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"

Execução de teste:

$ # 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

Responder2

Se as linhas que você não deseja tocar não têm vírgulas e você sempre deseja excluir apenas a primeira vírgula e tudo depois dela, você pode usar uma expressão muito simples

$ sed 's/,.*//' file
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123
  • s/old/new/substituir oldcomnew
  • .*qualquer número de qualquer caractere

Para editar o arquivo no local, use seda opção no local, que é -i. Se um sufixo para o arquivo de backup for adicionado após -i, ele grava automaticamente um backup do arquivo original com essa extensão no mesmo diretório, por exemplo

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

substitui filepelo fluxo modificado, mas

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

grava o fluxo modificado filee grava um novo arquivo file.origcom o conteúdo original.

Responder3

Você pode usar um cutcomando simples para fazer o que quiser.

cut -d"," -f1 input.txt

Escreva de volta no mesmo arquivo.

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

informação relacionada