如何使用命令行删除第二次出现引号后的所有内容?

如何使用命令行删除第二次出现引号后的所有内容?

我有这个存储在变量中

   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:一次性读取整个文件,而不是一次读取一行
  • -pwhile (<>) {[...]}在脚本周围放置一个循环并打印处理后的文件
  • -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"

相关内容