Как заменить пары строк в двух файлах на идентичные идентификаторы? - PullRequest
0 голосов
/ 20 апреля 2010

[Update2] Как это часто случается, объем задачи значительно расширился, если ее лучше понять. Устаревшие части вычеркнуты, и вы найдете обновленное объяснение ниже. [/ Update2]

У меня есть пара довольно больших файлов журнала с очень похожим содержимым, за исключением того, что некоторые строки отличаются между ними. Пара примеров:

UnifiedClassLoader3@19518cc | UnifiedClassLoader3@d0357a
JBossRMIClassLoader@13c2d7f | JBossRMIClassLoader@191777e

То есть, где первый файл содержит UnifiedClassLoader3@19518cc, второй содержит UnifiedClassLoader3@d0357a и так далее. [Обновить] Существует около 40 различных пар таких идентификаторов. [/ Update]

UnifiedClassLoader3@19518cc | UnifiedClassLoader3@d0357a
JBossRMIClassLoader@13c2d7f | JBossRMIClassLoader@191777e
Logi18n@177060f             | Logi18n@12ef4c6
LogFactory$1@15e3dc4        | LogFactory$1@2942da

То есть, где первый файл содержит UnifiedClassLoader3@19518cc, второй содержит UnifiedClassLoader3@d0357a и т. Д. Обратите внимание, что все эти строки находятся внутри длинных строк текста, и они появляются во многих строках, перемешанных друг с другом. Существует около 4000 различных пар таких идентификаторов, а размер каждого файла составляет около 34 МБ. Так что производительность тоже стала проблемой.

Я хочу заменить их на идентичные идентификаторы, чтобы я мог определить действительно важные различия между этими двумя файлами. То есть Я хочу заменить все вхождения UnifiedClassLoader3@19518cc в файле1 и UnifiedClassLoader3@d0357a в файле2 на UnifiedClassLoader3@1; все вхождения как Logi18n@177060f в файле1 и Logi18n@12ef4c6 в файле2 с Logi18n@2 и т. д. Счетчики 1 и 2 являются произвольными вариантами - единственное требование состоит в том, что между старым и старым новые строки (т. е. одна и та же строка всегда заменяется одним и тем же значением, а разные строки не заменяются одним и тем же значением).

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

grep -o -e 'ClassLoader[0-9]*@[0-9a-f][0-9a-f]*' file1.log | sort | uniq

grep -o -e '[A-Z][A-Za-z0-9]*\(\$[0-9][0-9]*\)*@[0-9a-f][0-9a-f]*' file1.log
    | sort | uniq

Однако, теперь первоначальный порядок потерян, поэтому я не знаю, какая пара идентификатора в другом файле. С помощью grep -n я могу получить номер строки, чтобы сортировка сохраняла порядок появления, но тогда я не могу отсеять повторяющиеся вхождения. К сожалению, grep не может распечатать только первое совпадение шаблона.

Я подумал, что могу сохранить список идентификаторов, созданных вышеупомянутой командой, в файл, затем перебрать шаблоны в файле с помощью grep -n | head -n 1, объединить результаты и снова отсортировать их. Результат будет что-то вроде

2 ClassLoader3@19518cc
137 ClassLoader@13c2d7f
563 ClassLoader3@1267649
...

Тогда я мог бы (используя sed сам) преобразовать это в sed команду, подобную

sed -e 's/ClassLoader3@19518cc/ClassLoader3@2/g' 
    -e 's/ClassLoader@13c2d7f/ClassLoader@137/g' 
    -e 's/ClassLoader3@1267649/ClassLoader3@563/g' 
    file1.log > file1_processed.log

и аналогично для файла 2.

Однако, прежде чем я начну, я хотел бы убедиться, что мой план - самое простое из возможных рабочих решений для этого.

Есть ли какой-либо недостаток в этом подходе? Есть ли более простой способ?

1 Ответ

1 голос
/ 21 апреля 2010

Я думаю, что это делает трюк, или, по крайней мере, близко

#!/bin/sh
for PREFIX in file1 file2
do
    cp ${PREFIX}.log /tmp/filter.$$.txt
    FILE_MAP=`egrep -o -e 'ClassLoader[0-9a-f]*@[0-9a-f]+' ${PREFIX}.log | uniq | egrep -n .`
    for MAP in `echo $FILE_MAP`
    do
        NUMBER=`echo $MAP | cut -d : -f 1` 
        WORD=`echo $MAP | cut -d : -f 2`
        sed -e s/$WORD/ClassLoader@$NUMBER/g /tmp/filter.$$.txt > ${PREFIX}_processed.log
        cp ${PREFIX}_processed.log /tmp/filter.$$.txt
    done
    rm /tmp/filter.$$.txt
done

Дайте мне знать, если у вас есть вопросы о том, как это работает и почему.

Вот мои тестовые данные и вывод

File1.log:

A1
UnifiedClassLoader3@a45bc1
A2
UnifiedClassLoader3@a45bc1
A3
UnifiedClassLoader3@a45bc1
A4
JBossRMIClassLoader@bc450a
A5
JBossRMIClassLoader@bc450a
A6
JBossRMIClassLoader@bc450a

B1
UnifiedClassLoader3@a45bc2
B2
UnifiedClassLoader3@a45bc2
B3
UnifiedClassLoader3@a45bc2
B4
JBossRMIClassLoader@bc450b
B5
JBossRMIClassLoader@bc450b
B6
JBossRMIClassLoader@bc450b

C1
UnifiedClassLoader3@a45bc3
C2
UnifiedClassLoader3@a45bc3
C3
UnifiedClassLoader3@a45bc3
C4
JBossRMIClassLoader@bc450c
C5
JBossRMIClassLoader@bc450c
C6
JBossRMIClassLoader@bc450c

file2.log (Аналогичные шаблоны, за исключением набора «C», повторяют набор «A»)

A1
UnifiedClassLoader3@d0357a
A2
UnifiedClassLoader3@d0357a
A3
UnifiedClassLoader3@d0357a
A4
JBossRMIClassLoader@191777e
A5
JBossRMIClassLoader@191777e
A6
JBossRMIClassLoader@191777e

B1
UnifiedClassLoader3@d0357b
B2
UnifiedClassLoader3@d0357b
B3
UnifiedClassLoader3@d0357b
B4
JBossRMIClassLoader@191777f
B5
JBossRMIClassLoader@191777f
B6
JBossRMIClassLoader@191777f

C1
UnifiedClassLoader3@d0357a
C2
UnifiedClassLoader3@d0357a
C3
UnifiedClassLoader3@d0357a
C4
JBossRMIClassLoader@191777e
C5
JBossRMIClassLoader@191777e
C6
JBossRMIClassLoader@191777e

И после обработки вы получите file1_processed.log

A1
UnifiedClassLoader@1
A2
UnifiedClassLoader@1
A3
UnifiedClassLoader@1
A4
JBossRMIClassLoader@2
A5
JBossRMIClassLoader@2
A6
JBossRMIClassLoader@2

B1
UnifiedClassLoader@3
B2
UnifiedClassLoader@3
B3
UnifiedClassLoader@3
B4
JBossRMIClassLoader@4
B5
JBossRMIClassLoader@4
B6
JBossRMIClassLoader@4

C1
UnifiedClassLoader@5
C2
UnifiedClassLoader@5
C3
UnifiedClassLoader@5
C4
JBossRMIClassLoader@6
C5
JBossRMIClassLoader@6
C6

и file2_processed.log

A1
UnifiedClassLoader@1
A2
UnifiedClassLoader@1
A3
UnifiedClassLoader@1
A4
JBossRMIClassLoader@2
A5
JBossRMIClassLoader@2
A6
JBossRMIClassLoader@2

B1
UnifiedClassLoader@3
B2
UnifiedClassLoader@3
B3
UnifiedClassLoader@3
B4
JBossRMIClassLoader@4
B5
JBossRMIClassLoader@4
B6
JBossRMIClassLoader@4

C1
UnifiedClassLoader@1
C2
UnifiedClassLoader@1
C3
UnifiedClassLoader@1
C4
JBossRMIClassLoader@2
C5
JBossRMIClassLoader@2
C6
JBossRMIClassLoader@2
...