为什么这个正则表达式替换不起作用?

为什么这个正则表达式替换不起作用?

我有一个以下格式的文件:

$ cat myfile     
12 42956    Cinema - 3D/Multiplex    
7  12560    Status Update    
5  184   Movie  

我正在尝试在文本描述中添加双引号。
我不明白为什么以下正则表达式不起作用:
$ sed -E 's/\b[0-9]+\b\s*\b[0-9]+\b\s*([^\s]+)/"\1"/g' myfile

我的问题是关于这个正则表达式,而不是另一种做同样事情的方法。我

答案1

据我所知,是一个 Perl 正则表达式,与中的\s相同。里面,意思是“一个和一个”。还要注意,即使与 相同,也会由于中间的空格而无法匹配。[[:blank:]]sed[ ... ]\s\s[^\s]+[^␣]+Status Update

替换将用双引号中的第一组替换所有匹配项。您可能想要捕获所有三列,否则您最终会得到仅有的 最后一栏。当您尝试匹配整行时,您应该使用^and将表达式锚定在开头和结尾,并在末尾$删除标志。g

选择:

$ sed -E 's/[[:alpha:]].+/"&"/' myfile
12 42956    "Cinema - 3D/Multiplex    "
7  12560    "Status Update    "
5  184   "Movie  "

这将找到最后一列,因为它的数据似乎总是以非数字开头。该表达式将简单地从第一个字母字符开始匹配该行的其余部分,并将所有匹配项替换为双引号版本的匹配项。

问题中的数据末尾有空格,引号中会包含这些空格。要避免末尾出现空格,请执行以下操作:

$ sed -E -e 's/[[:blank:]]*$//' -e 's/[[:alpha:]].+/"&"/' myfile
12 42956    "Cinema - 3D/Multiplex"
7  12560    "Status Update"
5  184   "Movie"

或者,

while read -r a b c; do printf '%d\t%d\t"%s"\n' "$a" "$b" "$c"; done <myfile
12      42956   "Cinema - 3D/Multiplex"
7       12560   "Status Update"
5       184     "Movie"

答案2

sed -E 's/\b([0-9]+\b\s*\b[0-9]+)\b\s*([^\s]+)/\1 "\2"/g' myfile

这只会在文本周围添加双引号。

将数字和空格保存在一组中\1,将字符串保存在另一组 (\2) 中,sed 输出组 1 (\1),后跟空格,后跟双引号,然后是第二组 (\2),最后是双引号引用。

([0-9, ]*)您可以通过将所有数字和空格分组为一组并将数字后面的任何内容分组为另一组来缩短这一时间(.+)

这给出:

sed -E 's/([0-9, ]*)(.+)/\1 "\2"/g' myfile
12 42956     "Cinema - 3D/Multiplex"
7  12560     "Status Update"
5  184    "Movie"

答案3

因为 Mac OSXsed不支持\s.仅GNU sed支持\s.

在 Mac OSX 上,即使使用ANSI-C 引用,\s也不起作用。$''

$ echo $'1\t2 3' | sed 's/\s//g'
1   2 3
$ echo $'1\t2 3' | sed $'s/\s//g'
1   2 3

相反,您可以使用[[:space:]]

$ echo $'1\t2 3' | sed 's/[[:space:]]//g'
123

或者您可以使用[ \t],但您需要$''对制表符进行 ANSI-C 引用。

$ echo $'1\t2 3' | sed $'s/[ \t]//g'
123

相关内容