Como cortar texto de um arquivo e gravar as alterações no mesmo arquivo?

1

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,

Eu 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 gravar 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 posso fazer isso?

    
por Anony 23.10.2017 / 14:15

3 respostas

4

Pelo que entendi, 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

Existem várias maneiras de fazer isso, então escolha o método que você deseja / gostar / preferir.

sed

$ sed 's/\(error code:[[:blank:]][[:digit:]]*\),.*//' 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 apenas sed

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

Essa abordagem faz com que a vírgula seja tratada como separador de coluna (no campo "awk-speak"), portanto, basicamente encontramos uma linha que começa com error code text e substitui a linha original pela coluna $1 , que no seu caso passa a ser tudo antes da vírgula, ou seja, error code: 123 .

awk não pode fazer edição no texto (a maioria das versões), como sed -i , mas você sempre pode exportar itens para um novo arquivo e substituir o arquivo antigo por novo como:

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

bash puro

#!/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
    
por Sergiy Kolodyazhnyy 24.10.2017 / 04:52
3

Se as linhas que você não quer tocar não tiverem vírgulas, e você sempre quiser excluir apenas a primeira vírgula e tudo depois dela, você poderá 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/ replace old com new
  • .* qualquer número de caracteres

Para editar o arquivo, use a opção no local sed , que é -i . Se um sufixo para o arquivo de backup for adicionado após -i , ele gravará 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 em file e grava um novo arquivo file.orig no conteúdo original.

    
por Zanna 24.10.2017 / 09:58
1

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

cut -d"," -f1 input.txt

Escreva de volta para o mesmo arquivo.

cut -d"," -f1 input.txt | tee input.txt
    
por Ziazis 26.10.2017 / 14:48