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 XXXXXXXX
e manter error code: 123
das 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 -i
em 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 code
texto e substituímos a linha original por apenas column $1
, que no seu caso é tudo antes da vírgula, ou seja error code: 123
.
awk
não é possível fazer edição de texto (na maioria das versões), sed -i
mas 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/
substituirold
comnew
.*
qualquer número de qualquer caractere
Para editar o arquivo no local, use sed
a 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 file
pelo fluxo modificado, mas
sed -i.orig 's/,.*//' file
grava o fluxo modificado file
e grava um novo arquivo file.orig
com o conteúdo original.
Responder3
Você pode usar um cut
comando 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