根据下一行内容删除特定文本

根据下一行内容删除特定文本

我需要一个命令来根据下一行的内容删除特定文本,特别是如果下一行是“]”,我想删除“逗号”,并删除下一行“]”。

例子

987678680,
]
123435434-
]
2345643,
]
2345632-
]
234563,
]
1234567654,
]

输出

987678680
123435434-
]
2345643
2345632-
]
234563
1234567654

答案1

在处理此类任务时(如果连续行匹配特定模式,则编辑/执行某些操作),最简单的方法sed可能是通过N;P;D循环又名“滑动窗口”:

sed -e '$!N;s/,\nPATTERN//;t' -e 'P;D' file

这会将Next 行放入模式空间,并无条件地尝试s根据要求进行替换。然后它t会判断替换是否成功:如果是,则分支到脚本末尾(无标签)并自动打印模式空间,否则它P会打印并D删除模式空间中的第一行并重新启动循环。


其他GNU sed方法:

sed ':x /,$/{N;s/,\n]//;T x}' file

即使尾随逗号位于偶数行,此方法也能正常工作。例子:

printf '%s\n' 1, 2, ']' | sed ':x /,$/{N;s/,\n]//;T x}'

输出:

1,
2

怎么运行的:

在大多数编程语言中,地址标签完全是被动的——标签标记代码,但永远不会改变该代码的操作。 不是 sed尽管。跳转sed到程序开头的标签实际上改变了代码的操作,或者更确切地说,它避免了隐式的n外线sed循环通常开始的代码。

T如果失败则进行 est 和分支命令T x检查是否先前s替代品命令不执行任何操作,如果是则跳转到:x开头的标签没有打印任何内容或读取新行。这意味着由追加N分机行未被替换的将被重新扫描,正如它应该的那样。


对于非GNU sed,(当T命令不可用并且语法不那么宽松时),这应该更可移植:

sed ':x
/,$/{
N
s/,\n]//
t
b x
}' file

答案2

您可以sed 按如下方式使用:

sed -e '/,$/{N; /\]/s/,[^,]*$//;}' file
987678680
123435434-
]
2345643
2345632-
]
234563
1234567654

或者根据@steeldriver,这可以简化如下Bash

sed '$!N; s/,\n]//'

相关内容