У меня есть это хранилище в переменной
sCellEventTrap-03-28 TRAP-TYPE -- CAC Code: 00 ENTERPRISE compaq VARIABLES { scellNameDateTime, scellSWComponent, scellECode, scellCAC, scellEIP} DESCRIPTION "Severity: Normal -- informational in nature. A physical disk drive has experienced an ID block inconsistency during a periodic drive check." --#TYPE "StorageCell Event" --#SUMMARY "SCellName-TimeDate %s : SWCID %d : ECode: %d : CAC %d : EIP %d." --#ARGUMENTS {0,1,2,3,4,} --#SEVERITY INFORMATIONAL --#TIMEINDEX 136 --#STATE WARNING ::= 13600808
Я должен сократить все до второго возникновения "
. Таким образом, это дало бы мне:
sCellEventTrap-03-28 TRAP-TYPE -- CAC Code: 00 ENTERPRISE compaq VARIABLES { scellNameDateTime, scellSWComponent, scellECode, scellCAC, scellEIP} DESCRIPTION "Severity: Normal -- informational in nature. A physical disk drive has experienced an ID block inconsistency during a periodic drive check."
Другой пример
genericSanEvent TRAP-TYPE ENTERPRISE hpSanManager VARIABLES { severityLevel, category, id, msgString, contactName, contactEmail, contactWorkPhone, contactHomePhone, contactPager, contactFax } DESCRIPTION "A generic SAN event has occurred. The variables are: severityLevel - the event severity level; category - Category of the event being reported; code - ID of the event in the given category; msgString - the message string describing the event; contactName - the name of the individual to be notified of the event; contactEmail - the e-mail address of the individual referred to in contactName; contactWorkPhone - the work phone number of the individual referred to in contactName; contactHomePhone - the home phone number of the individual referred to in contactName; contactPager - the pager number of the individual referred to in contactName; contactFax - the FAX number of the individual referred to in contactName" -- The following are attributes used by xnmloadmib for improved formatting --#TYPE "OV SAM SAN Event" --#SUMMARY "OV SAM SAN Event, Category/Id: %d/%d, Msg: %d Severity: %d Contact: %d" --#ARGUMENTS {1,2,3,0,4} --#SEVERITY CRITICAL --#GENERIC 6 --#CATEGORY "Application Alert Events" --#SOURCE_ID "T" ::= 1
Вывод для этого примера должен быть:
genericSanEvent TRAP-TYPE ENTERPRISE hpSanManager VARIABLES { severityLevel, category, id, msgString, contactName, contactEmail, contactWorkPhone, contactHomePhone, contactPager, contactFax } DESCRIPTION "A generic SAN event has occurred. The variables are: severityLevel - the event severity level; category - Category of the event being reported; code - ID of the event in the given category; msgString - the message string describing the event; contactName - the name of the individual to be notified of the event; contactEmail - the e-mail address of the individual referred to in contactName; contactWorkPhone - the work phone number of the individual referred to in contactName; contactHomePhone - the home phone number of the individual referred to in contactName; contactPager - the pager number of the individual referred to in contactName; contactFax - the FAX number of the individual referred to in contactName"
awk -v RS='"' -v ORS='"' 'NR==1{print} NR==2{print; printf"\n";exit}' file
Это устанавливает разделитель записей на "
. Так, мы хотим распечатать первые две записи, и затем мы сделаны. Более подробно:
-v RS='"'
Это устанавливает входной разделитель записей на двойную кавычку.
-v ORS='"'
Это устанавливает разделитель записей на двойную кавычку.
NR==1{print}
Это говорит awk печатать первую строку.
NR==2{print; printf"\n";exit}
Это говорит awk печатать вторую строку, затем печатать символ новой строки, и затем выходить.
sed -r 'H;1h;$!d;x; s/(([^"]*"){2}).*/\1/' file
Это читает целый файл в сразу. Так, если файл огромен, не используйте этот подход. Это работает следующим образом:
H;1h;$!d;x
Это - полезная sed идиома: это читает целый файл в сразу.
s/(([^"]*"){2}).*/\1/
Это ищет второе "
и затем удаляет весь текст, который следует за второй кавычкой.
regex (([^"]*"){2})
получает весь текст до и включая вторую двойную кавычку и сохраняет его в группе 1. regex .*
получает все, что следует до конца файла. Текст замены является группой 1, \1
.
Используя Perl:
< infile perl -0777 -pe 's/((.*?"){2}).*/$1/s' > outfile
-0777
: хлебает целый файл сразу вместо одной строки в то время -p
: помещает while (<>) {[...]}
цикл вокруг сценария и печатает обработанный файл -e
: читает сценарий из аргументов разбивка команды Perl:
s
: утверждает для выполнения замены /
: запускает шаблон ((.*?"){2})
: соответствия и группы любое количество любого символьного нуля или больше раз лениво в текущем файле (т.е. это соответствует наименьшее количество раз как возможное, останавливаясь, когда следующий шаблон начинает соответствовать), перед "
символ, дважды .*
: соответствуют любое количество любого символьного нуля или больше раз жадно в текущем файле (т.е. это соответствует большинство раз как возможное) /
: останавливается шаблон / запускает замещающую строку $1
: замены первой полученной группой /
: останавливается замещающая строка / запускает модификаторы s
: рассматривает целый файл как одну строку, позволяя .
соответствовать также новым строкам Вот немного python
сценарий:
#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
print '"'.join(f.read().split('"')[:2]) + '"'
f.read().split('"')
считает целый файл как строку и затем разделит его на "
для получения весь "
разделенные части
, Поскольку мы интересуемся только первым два "
, разделенные части, '"'.join(f.read().split('"')[:2])
присоединятся к первым двум с "
Тогда наконец, мы добавили "
для получения нужного формата.
Вот более короткое awk
версия: awk '/TRAP-TYPE/,/[[:alpha:]]*"$/ '
$ awk '/TRAP-TYPE/,/[[:alpha:]]*"$/ ' testfile.txt
sCellEventTrap-03-28 TRAP-TYPE -- CAC Code: 00
ENTERPRISE compaq
VARIABLES { scellNameDateTime,
scellSWComponent,
scellECode,
scellCAC,
scellEIP}
DESCRIPTION
"Severity: Normal -- informational in nature. A physical disk drive has experienced an ID block inconsistency during a periodic drive check."
$ awk '/TRAP-TYPE/,/[[:alpha:]]*"$/ ' testfile2.txt
genericSanEvent TRAP-TYPE
ENTERPRISE hpSanManager
VARIABLES { severityLevel, category, id,
msgString, contactName, contactEmail,
contactWorkPhone, contactHomePhone,
contactPager, contactFax }
DESCRIPTION
"A generic SAN event has occurred. The variables are:
severityLevel - the event severity level;
category - Category of the event being reported;
code - ID of the event in the given category;
msgString - the message string describing
the event;
contactName - the name of the individual
to be notified of the event;
contactEmail - the e-mail address of the
individual referred to in contactName;
contactWorkPhone - the work phone number
of the individual referred to in
contactName;
contactHomePhone - the home phone number
of the individual referred to in
contactName;
contactPager - the pager number of the
individual referred to in contactName;
contactFax - the FAX number of the individual
referred to in contactName"
Хотя многим программам не нравятся очень длинные строки, как введено, когда Ваши данные не огромны, можно часто упрощать соответствие мультилинии первым управлением данными для помещения всего этого на одну строку, делая соответствие, затем восстанавливая новые строки.
Например, используйте TR для замены новой строки \n
некоторым символом не в Ваших данных (я использовал возврат каретки '\r'), используйте sed для изменения этой одной строки, затем TR символ назад:
tr '\n' '\r' < file |
sed 's/\("[^"]*"\).*/\1/' |
( tr '\r' '\n'; echo ) # add a final newline
Иначе, хотя Вы заявляете о желании sed/awk/grep языки как жемчуг и Python используют подобные регулярные выражения в качестве них и хороши для управления многострочными строками. Например, жемчуг:
perl -e '$_ = join("",<>); s/(".*?").*/$1/s; print "$_\n"; ' file