Как сократить текст из файла и записать изменения в том же файле?

У меня есть файл как:

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

Я должен сохранить строки с меткой времени, т.е. 171023 03014426 1234 XXXX XXXXXXXX и сохраните error code: 123 от других строк, т.е. от запуска строки до запятой и записи изменения в том же файле.

Вывод:

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

Как я могу сделать это?

1
задан 24 October 2017 в 10:59

3 ответа

Поскольку я понимаю Ваш вопрос, Вы хотите это

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

стать этим:

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

Существует много способов сделать это, поэтому выберите метод, который Вы хотите/любите/предпочитаете.

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

Если Вы хотите внести изменения в исходный файл input.txt, использовать sed -i вместо просто 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

Этот подход делает запятую, которую будут рассматривать как столбец (в, awk-говорят "поле"), разделитель, таким образом, здесь мы в основном находим строку, которая запускается с error code текст и заменяет исходную строку только столбцом $1, который в Вашем случае, оказывается, все перед запятой, т.е. error code: 123.

awk не может сделать в редактировании текста (большинство версий), как sed -i но можно всегда производить вещи в новый файл и заменять старый файл новым как:

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

чистый удар

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

Тестовый прогон:

$ # 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
4
ответ дан 3 December 2019 в 06:22

Если строки, которых Вы не хотите касаться, не имеют никаких запятых, и Вы всегда хотите только удалить первую запятую и все после него, можно использовать очень простое выражение

$ sed 's/,.*//' file
171023 03014426 1234 XXXX XXXXXXXX
error code: 123
171023 03110749 1234 XXXX XXXXXXXX
error code: 123
  • s/old/new/ замена old с new
  • .* любое количество любых символов

Для редактирования файла на месте использовать sedоперативная опция, которая является -i. Если суффикс для файла резервной копии добавляется после -i, это автоматически пишет резервное копирование исходного файла с тем расширением в том же каталоге, например

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

перезаписи file с измененным потоком, но

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

пишет измененный поток в file и пишет новый файл file.orig с исходным содержанием.

3
ответ дан 3 December 2019 в 06:22

Можно использовать простое cut команда, чтобы сделать то, что Вы хотите.

cut -d"," -f1 input.txt

Запишите его обратно в тот же файл.

cut -d"," -f1 input.txt | tee input.txt
1
ответ дан 3 December 2019 в 06:22

Другие вопросы по тегам:

Похожие вопросы: