首页 > 解决方案 > 使用 sed 将每列替换为不同的间距

问题描述

我正在尝试为输入文件的每一列替换不同的模式。

输入文件

this- START
this-        START

我想要的结果

/this/ -START-
/this/ -START-

我的代码

sed 's|^\([a-zA-Z]*\)-\s\([a-zA-Z]*\)$|/\1/ -\2-|' inputfile

输出

/this/ -START-
this-        START 

第一个输入有效,但带有大量空格的第二个输入无效。如何使用同一行代码处理它们?

标签: linuxsed

解决方案


sed使用 POSIX 基本正则表达式,顾名思义,它们非常基本,没有很多您可能更习惯的其他 RE 包的语法糖或功能。但他们仍然可以处理这个:

$ cat input.txt
this- START
this-           START
$ sed 's!^\([a-zA-Z]*\)-[[:space:]]\{1,\}\([a-zA-Z]*\)$!/\1/ -\2-!' input.txt
/this/ -START-
/this/ -START-

这里的关键在于[[:space:]]\{1,\}部分:[:space:][]字符类内部匹配任何空白字符,就像\s在其他 RE 实现中一样,并\{1,\}匹配 1 个或多个前面的原子,就像+在几乎所有其他风格中一样(它也支持这种表示法,尽管不需要反斜杠)。所以结合起来它匹配 1 个或多个空白字符。而且由于正则表达式是贪婪的,它匹配最长的空白字符序列,而不是在看到一个之后就停止。

如果您在列之间只有空格,而不是空格和/或制表符,则可以将其简化为\{1,\}(注意前导文字空格;在呈现的降价中并不明显)。您可以使用[[:alpha:]]而不是[a-zA-Z]匹配所有字母字符。如果匹配非英文文本会有所不同。如果它们可以显示在您的输入中,您可能希望使用\{1,\}而不是*避免匹配 0 长度/缺失的列。


推荐阅读