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

У меня есть файл вроде:

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

6 ответов

Как я понимаю ваш вопрос, вы хотите, чтобы этот

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

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

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-talk «поле») разделитель, поэтому здесь мы в основном находим строку, которая начинается с текста 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

pure bash

#!/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
ответ дан 18 July 2018 в 04:45

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

$ 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 с измененным stream, но

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

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

3
ответ дан 18 July 2018 в 04:45

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

cut -d"," -f1 input.txt

Записать ее в тот же файл.

cut -d"," -f1 input.txt | tee input.txt
1
ответ дан 18 July 2018 в 04:45

Как я понимаю ваш вопрос, вы хотите, чтобы этот

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

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

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-talk «поле») разделитель, поэтому здесь мы в основном находим строку, которая начинается с текста 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

pure bash

#!/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
ответ дан 24 July 2018 в 18:09
  • 1
    Вместо IFS= read, используя IFS=, read -r line extra, вы можете бесплатно получить деталь перед запятой. – muru 24 October 2017 в 06:01
  • 2
    @muru да, я тоже думал об этом; вероятно, это лучше – Sergiy Kolodyazhnyy 24 October 2017 в 06:07
  • 3
    Почему не простой cut -d"," -f1? – Ziazis 26 October 2017 в 15:39
  • 4
    @Ziazis уверен, может работать достаточно хорошо. – Sergiy Kolodyazhnyy 27 October 2017 в 01:57

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

$ 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 с измененным stream, но

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

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

3
ответ дан 24 July 2018 в 18:09

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

cut -d"," -f1 input.txt

Записать ее в тот же файл.

cut -d"," -f1 input.txt | tee input.txt
1
ответ дан 24 July 2018 в 18:09

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

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