разбивая файл вниз - PullRequest
       9

разбивая файл вниз

0 голосов
/ 25 ноября 2011

У меня большой лог-файл, более 1 миллиона строк.Мне нужно использовать regexp, чтобы найти шаблон, а затем начать сжимать, пока я не столкнусь с другим регулярным выражением.Таким образом, я получу примерно 1500 строк.

Я знаю, что sed позволяет использовать регулярные выражения, но может ли он разбивать файлы?У меня нет опыта работы с awk, но я думаю, что это должно позволить мне делать то, что мне нужно.Я смущен тем, что читаю справочную страницу ... Я бы оценил некоторые примеры или даже более простые решения.

Ответы [ 3 ]

5 голосов
/ 25 ноября 2011

В обоих AWK и SED вы можете определить RegEx следующим образом -

AWK: В AWK вы заметите, что мы нигде не написали print. В AWK (который основан на операторах pattern / action, print является действием по умолчанию всякий раз, когда выражение pattern является истинным. Следовательно, в следующем случае, когда шаблон RegEx имеет значение true, AWK распечатает его для нас.

awk '/regex1/,/regex2/' INPUT_FILE > NEW_FILE

SED: В SED мы используем опцию -n, чтобы подавить поведение по умолчанию при печати всего, и используем RegEx с p, чтобы сообщить SED о печати определенных строк.

sed -n '/regex1/,/regex2/p' INPUT_FILE > NEW_FILE

В качестве альтернативы вы также можете указать следующую однострочную строку

sed '/regex1/,/regex2/!d' INPUT_FILE > NEW_FILE

Используя оператор перенаправления >, вы можете создать подмножество вашего файла.

Для Разделение файлов в AWK , если вы знаете количество записей в вашем файле (wc -l < INPUT_FILE), то вы можете написать что-то вроде этого -

awk 'NR==2,NR==5' INPUT_FILE

NR - встроенная переменная AWK, для которой устанавливается номер строки записи. Так что, если у вас есть файл с 1500 строками и вам нужен только верхний 750, то вы можете сделать что-то вроде этого -

awk 'NR==1,NR==750' INPUT_FILE

Как упоминалось ранее, вы можете, но не обязательно указывать print с AWK. Он делает это для вас, пока ваш шаблон верен

Хотя в вашем файле миллион строк, это будет серьезной болью. Таким образом, следующий AWK с одним вкладышем должен сделать свое дело.

awk '{print >("SMALL_BATCH_OF_FILES_" int((NR+2)/3))}' BIG_INPUT_FILE

Этот однострочник создаст SMALL_BATCH_OF_FILES_, содержащий 3 строки в каждой. Вы можете установить это на свой уровень комфорта. (NR + 2/3) * * одна тысяча тридцать шесть

Исполнение:

[jaypal~/Temp]$ cat BIG_INPUT_FILE 
1
2
3
4
5
6
7
8
9
10

[jaypal~/Temp]$ awk '{print >("SMALL_BATCH_OF_FILES_" int((NR+2)/3))}' BIG_INPUT_FILE

[jaypal~/Temp]$ ls -lrt SMALL*
-rw-r--r--  1 jaypalsingh  staff  3 25 Nov 10:41 SMALL_BATCH_OF_FILES_4
-rw-r--r--  1 jaypalsingh  staff  6 25 Nov 10:41 SMALL_BATCH_OF_FILES_3
-rw-r--r--  1 jaypalsingh  staff  6 25 Nov 10:41 SMALL_BATCH_OF_FILES_2
-rw-r--r--  1 jaypalsingh  staff  6 25 Nov 10:41 SMALL_BATCH_OF_FILES_1

[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_1 
1
2
3
[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_2 
4
5
6
[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_3
7
8
9
[jaypal~/Temp]$ cat SMALL_BATCH_OF_FILES_4
10
1 голос
/ 25 ноября 2011

perl -ne 'print if /start pattern/ .. /end pattern/' напечатает любую последовательность строк, начинающуюся с одной, которая соответствует /start pattern/ и заканчивающуюся одной, которая соответствует /end pattern/ Если вы хотите выручить после первого такого блока, вы можете использовать perl -ne 'print if /start pattern/ .. 0; last if /end pattern/'.

Первый также можно сделать в awk: /start pattern/, /end pattern/ { print }.

Второй, вероятно, можно сделать и в awk, но я не знаю, как много awk.

0 голосов
/ 25 ноября 2011

Просто пример решения, которое уже было предложено

awk '/regexp1/,/regexp2/'

Предположительно, ваш входной файл

0 zzz
1 aaa
2 bbb
3 ccc
4 aaa
5 ddd
6 ccc
7 aaa
8 ddd
9 eee
10 ddd
11 zzz

, команда

awk '/a/, /d/' file.txt

извлечетдва подмножества: строки с 1 по 5 (примечание 4 aaa игнорируется) и строки с 7 по 8 (примечание 10 ddd игнорируется)

1 aaa
2 bbb
3 ccc
4 aaa
5 ddd
7 aaa
8 ddd
...