我需要一个命令来根据下一行的内容删除特定文本,特别是如果下一行是“]”,我想删除“逗号”,并删除下一行“]”。
例子
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
这会将N
ext 行放入模式空间,并无条件地尝试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]//'