我有这个存储在变量中
sCellEventTrap-03-28 TRAP-类型 -- CAC 代码:00 企业 康柏 变量 { scellNameDateTime, scellSW组件, scellE代码, 细胞CAC, } 描述 “严重性:正常 - 信息性。物理磁盘驱动器在定期驱动器检查期间遇到 ID 块不一致问题。” --#TYPE "存储单元事件" --#SUMMARY “SCellName-TimeDate %s:SWCID %d:ECode:%d:CAC %d:EIP %d。” --#参数{0,1,2,3,4,} --#严重性信息 --#时间索引 136 --#国家警告 ::= 13600808
我要剪切所有内容直到第二次出现"
。这样我会得到:
sCellEventTrap-03-28 TRAP-类型 -- CAC 代码:00 企业 康柏 变量 { scellNameDateTime, scellSW组件, scellE代码, 细胞CAC, } 描述 “严重性:正常 - 信息性。物理磁盘驱动器在定期驱动器检查期间遇到 ID 块不一致问题。”
另一个例子
genericSanEvent TRAP-TYPE 企业 hpSanManager 变量 { 严重性级别, 类别, id, msgString,联系人姓名,联系人电子邮件, 联系工作电话、联系家庭电话、 联系传呼机,联系传真 } 描述 “发生了一般 SAN 事件。变量包括: dangerlevel - 事件严重性级别; 类别——所报告事件的类别; code - 给定类别中事件的 ID; msgString - 描述消息字符串 事件; contactName - 个人姓名 收到事件通知; contactEmail - 电子邮件地址 联系人姓名中提及的个人; contactWorkPhone - 工作电话号码 所提及的个人 联系人姓名; contactHomePhone - 家庭电话号码 所提及的个人 联系人姓名; contactPager - 的寻呼机号码 联系人姓名中提及的个人; contactFax - 个人的传真号码 联系人姓名” -- 以下是 xnmloadmib 用于改进格式的属性 --#TYPE "OV SAM SAN 事件" --#SUMMARY “OV SAM SAN 事件,类别/ID:%d/%d,消息:%d 严重性:%d 联系人:%d” --#参数{1,2,3,0,4} --#严重程度严重 --#通用 6 --#CATEGORY "应用程序警报事件" --#SOURCE_ID “T” ::= 1
此示例的输出应为:
genericSanEvent TRAP-TYPE 企业 hpSanManager 变量 { 严重性级别, 类别, id, msgString,联系人姓名,联系人电子邮件, 联系工作电话、联系家庭电话、 联系传呼机,联系传真 } 描述 “发生了一般 SAN 事件。变量包括: dangerlevel - 事件严重性级别; 类别——所报告事件的类别; code - 给定类别中事件的 ID; msgString - 描述消息字符串 事件; contactName - 个人姓名 收到事件通知; contactEmail - 电子邮件地址 联系人姓名中提及的个人; contactWorkPhone - 工作电话号码 所提及的个人 联系人姓名; contactHomePhone - 家庭电话号码 所提及的个人 联系人姓名; contactPager - 的寻呼机号码 联系人姓名中提及的个人; contactFax - 个人的传真号码 联系人姓名”
答案1
使用 awk:
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
sed -r 'H;1h;$!d;x; s/(([^"]*"){2}).*/\1/' file
这会一次性读取整个文件。因此,如果文件很大,请不要使用此方法。它的工作原理如下:
H;1h;$!d;x
这是一个有用的 sed 习惯用法:它一次读入整个文件。
s/(([^"]*"){2}).*/\1/
这将查找第二个引号
"
,然后删除第二个引号后面的所有文本。正则表达式
(([^"]*"){2})
捕获直到第二个双引号(包括它)的所有文本,并将其保存在组 1 中。正则表达式.*
捕获到文件末尾的所有内容。替换文本是组 1\1
,。
答案2
使用 Perl:
< infile perl -0777 -pe 's/((.*?"){2}).*/$1/s' > outfile
-0777
:一次性读取整个文件,而不是一次读取一行-p
:while (<>) {[...]}
在脚本周围放置一个循环并打印处理后的文件-e
:从参数中读取脚本
Perl 命令分解:
s
:断言执行替换/
:开始模式((.*?"){2})
:在当前文件中,对任意数量的任意字符进行零次或多次惰性匹配和分组(即,匹配次数尽可能少,当以下模式开始匹配时停止),在字符前"
,两次.*
:在当前文件中贪婪地匹配任意数量的任意字符零次或多次(即尽可能匹配最多的次数)/
:停止模式/开始替换字符串$1
: 用第一个捕获的组替换/
:停止替换字符串/启动修饰符s
: 将整个文件视为一行,允许.
匹配换行符
答案3
尽管许多程序不喜欢输入很长的行,但当你的数据不是很大时,你通常可以简化多行匹配首先处理数据,将其全部放在一行上,进行匹配,然后恢复换行符。
例如,使用 tr 将换行符替换\n
为数据中没有的某些字符(我使用了回车符“\r”),使用 sed 更改此单行,然后将字符 tr 回来:
tr '\n' '\r' < file |
sed 's/\("[^"]*"\).*/\1/' |
( tr '\r' '\n'; echo ) # add a final newline
否则,尽管您声明需要 sed/awk/grep,但 perl 和 python 等语言也使用类似的正则表达式,并且非常适合处理多行字符串。例如 perl:
perl -e '$_ = join("",<>); s/(".*?").*/$1/s; print "$_\n"; ' file
答案4
以下是较短的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"