Shell脚本:想要从特定行中删除匹配模式的两个连续行

Shell脚本:想要从特定行中删除匹配模式的两个连续行

我想删除文件中特定行中匹配模式的特定连续两行。

例如文件内容如下所示。

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc

我想找到从第 4 行开始的行,匹配以“Name:”开头的第一行模式,匹配以空格开头的第二行模式,并删除连续的两行。

有什么有效的方法可以使用 shellsed或其他方法来执行此操作吗?

更清楚地说,我想从 MANIFEST.MF 中删除签名/校验和信息。

示例 MANIFEST.MF 如下所示: 从下面的清单文件中,我想删除条目“Name:”。其中“名称:”条目可以位于一行或两行(或更多)行中。

最初我的解决方案就像找到第一个“Name:”条目,然后是“SHA-256-Digest:”条目并删除到文件末尾。不幸的是,该解决方案存在删除中间所需条目的问题。例如,“NetBeans-Simply-Convertible:”也将被删除。

因此,现在我想删除“Name:”条目(如果在 1 行中可用)或跨越 2 行或更多行的条目。但在删除“Name:”条目时,我不应该丢失“NetBeans-Simply-Convertible:”等条目。

我已经使用以下命令删除文件中的“SHA-256-Digest:”条目sed -i "/^\SHA-256-Digest: /d" $manifest_file


Manifest-Version: 1.0
Version-Info: ....

Name: com/abc/xyz/pqr/client/relationship/message/notifier/Relati
 onshipUpdateNotifierFactory.class
SHA-256-Digest: cSSyk6Y2L2F9N6FPtswUkxjF2kelMkGe4bFprcQ+3uY=

Name: com/abc/xyz/pqr/client/relationship/ui/BaseRelationshipView
 $5.class
SHA-256-Digest: w9HgRjDuP024U4CyxeKPYFe6rzuzxZF3b+9LVG36XP8=

Name: com/abc/xyz/pqr/client/impl/MofRelationshipAgentImpl.class
SHA-256-Digest: GwIBIU+UdPtjyRhayAVM90Eo+SwCT/kP65dI59adEnM=

Name: com/abc/xyz/pqr/client/settings/ConvertibleProperties.class
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties
SHA-256-Digest: 5FszAtfpPXcLx/6FBWbfeg6E4fwFMRozV+Q+3rReATc= ...

预期输出:

Manifest-Version: 1.0
Version-Info: ....


NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
 vertibleProperties

...

答案1

awk方法:

假设我们有以下输入文件file.txt(考虑到每行包含Line<number>:第一个字段):

Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5:  xyz
Line6: Name: 456
Line7:  abc
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc
Line12: Name: 333
Line13:  ccc

awk '{ if ($2 == "Name:") { 
           if ((getline l) > 0){ 
               if (l ~ /^\S+  \S+/) { next } else { print $0 RS l }               
           }
       } else { print } 
}' file.txt

输出:

Line1: a
Line2: b
Line3: c
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11:  abc

'获取线变量'- 从 awk 的输入中读取下一条记录到变量中var

获取线如果命令找到一条记录,则返回 1;如果遇到文件末尾,则返回 0。

答案2

你看你问的不清楚:一个答案删除了 4 行(匹配的两行和后续的两行);另一个删除所有内容匹配的线...

我将添加我所理解的你想要的内容:我删除 2 行,匹配的一行Name: 123和后续的一行。我用以下方法做到这一点sed

sed -e '/Name: 123/{N;d}' filename

答案3

使用ed

$ printf '%s\n' 'g/^ / s///\' '-,.j' 'g/^Name: /d' 'g/SHA-256-Digest: /d' '4,$g/^$/d' ,p Q | ed -s file
Manifest-Version: 1.0
Version-Info: ....

NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}ConvertibleProperties

这会将以下编辑脚本应用于您的输入文件:

g/^ / s///\
-,.j
g/^Name: /d
g/SHA-256-Digest: /d
4,$g/^$/d
,p
Q

这由六个单独的命令组成:

  1. 这两个命令s///应用于-,. j以空格字符开头的每一行。命令中的空正则表达式重复使用前一命令中的s表达式(用于将一个或多个命令应用于与正则表达式匹配的行),因此该命令删除以空格开头的行上的第一个空格。然后该命令将修改后的行与前一行连接起来。这有效地取消了输入数据中的换行。^gsj

  2. 该命令d适用于所有以 开头的行Name:,并将其删除。

  3. 同样,以 开头的行将SHA-256-Digest:被删除。

  4. 从第 4 行开始删除空行。

  5. 我们将完整的缓冲区输出到标准输出以显示结果。

  6. Q无条件退出编辑器(您可以wq将更改写回原始文件)。

答案4

sed -e '
   4,$!d;      # skip non-relevant portion
   /Name:/N;   # grab the line coming after Name:
   /\n.* /d;   # what we were after is not this
   P;D
' yourfile

相关内容