[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.
Однако, прежде чем я начну, я хотел бы убедиться, что мой план - самое простое из возможных рабочих решений для этого.
Есть ли какой-либо недостаток в этом подходе? Есть ли более простой способ?