Как удалить текст, соответствующий определенным шаблонам из файла

Поскольку это cp флагу недостает rsync:

-i, --interactive
       prompt before overwrite (overrides a previous -n option)
4
20.08.2014, 15:14
4 ответа

Если временные метки последовательно формируются, их можно снять (например, с помощью sed) перед обработкой файлов любым другим методом, например

diff <(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileA) <(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileB)

Тестирование предоставленных Вами входных файлов:

$ diff \
<(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileA) \
<(sed -E 's|[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{2,4} [0-9]{1,} ||' fileB)
2,3c2,3
< abc xxx
< ghi eee ddd
---
> abc def
> ghi fff ddd
2
27.01.2020, 20:58

Самой простой командой для получения результата была бы следующая

$ diff <(tr -s "[0-9],:,/" " " < fileA) <(tr -s "[0-9],:,/" " " < < fileB)

Команда очень прямая и сложного регулярного выражения тоже нет.

Пример вывода будет такой же, как ниже

2,3c2,3
< abc xxx
< ghi eee ddd
---
> abc def
> ghi fff ddd

Надеюсь, это то, что вам нужно.

0
27.01.2020, 20:58
diff \
<(sed -r 's\[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{6} \\' fileA) \
<(sed -r 's\[0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{6} \\' fileB) \
| egrep '^> ' | sed -r 's/^> //' > fileC

Пояснение

Удалите нерелевантные части, указанные в вопросе ОП, из файлов А и В и передайте их в diff.

diff выведет измененные разделы с предшествующим знаком «>», поэтому игнорируйте все остальное, кроме изменений.

Наконец, удалите начальный символ ">" из вывода и сохраните его в fileC в соответствии с вопросом.

Изначально я сделал это немного по-другому, но я просто заметил, что файлы могут отличаться в несоответствующем разделе, поэтому его нужно предварительно удалить, а не пост-разделить, иначе diff будет выводить информацию, которая на самом деле не изменилась при рассмотрении соответствующих частей. Только.

В примере ввода cat fileC дает:

abc def
ghi fff ddd

Команда sed ищет предоставленное регулярное выражение, которое описывает нерелевантные данные, и заменяет это пустой строкой, т. Е. Удаляет ее. .

1
27.01.2020, 20:58
{   paste -d\| /dev/fd/3 /dev/fd/4 |
    sed '/\([^ ]*\) [0-9:/ ]*\(.*\)|\1 .*\2/d;=' |
    sed 'N;s/\(\n\)\(.*\)|/:\tFILEA: \2\1\tFILEB: /'
} 3<<\FILEA 4<<\FILEB
qaqa rara
abc 10:12:25 08/20/2014 123456 def
ghi fff ddd
jkl 09:20:40 08/20/2014 978645 dfdf gggg
FILEA
qaqa rara
abc 10:32:15 07/15/2014 121456 xxx
ghi eee ddd
jkl 10:01:22 07/15/2014 971645 dfdf gggg
FILEB

ВЫВОД

2:      FILEA: abc 10:12:25 08/20/2014 123456 def
        FILEB: abc 10:32:15 07/15/2014 121456 xxx
3:      FILEA: ghi fff ddd
        FILEB: ghi eee ddd

Не нужно избавляться от времени и даты - они не представляют большого препятствия, если символы, их составляющие, надежны.

В указанном выше конвейере paste сначала добавляет соответствующую строку из FILEB в конец каждой из строк FILEA с одним | Затем разделитель распечатывает результаты в стандартный вывод .

sed выбирает поток и сравнивает:

  • первую последовательность из 0 или более символов, которые не являются пробелами (обозначено как \ 1 )

  • все символы, которые встречаются между следующими последовательностями: (обозначается как \ 2 )

    • хотя бы один символ <пробел> , затем 0 или более из любого из следующих значений:

    • символов

    • символов

    • <: двоеточие> символов

    • символов

  • до последнего, но не включая его встречающийся символ | в строке

... с | \ 1. * \ 2 . Если они совпадают, sed удаляет строку. В противном случае он печатает строку, которой предшествует ее номер.

Последний процесс sed просто улучшает вывод (надеюсь) .

0
27.01.2020, 20:58

Теги

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