我想删除文件中特定行中匹配模式的特定连续两行。
例如文件内容如下所示。
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
这由六个单独的命令组成:
这两个命令
s///
应用于-,. j
以空格字符开头的每一行。命令中的空正则表达式重复使用前一命令中的s
表达式(用于将一个或多个命令应用于与正则表达式匹配的行),因此该命令删除以空格开头的行上的第一个空格。然后该命令将修改后的行与前一行连接起来。这有效地取消了输入数据中的换行。^
g
s
j
该命令
d
适用于所有以 开头的行Name:
,并将其删除。同样,以 开头的行将
SHA-256-Digest:
被删除。从第 4 行开始删除空行。
我们将完整的缓冲区输出到标准输出以显示结果。
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