Gre*_*hal 44 shell sed regular-expression
我似乎无法让它发挥作用。GNU sed 文档说要转义管道,但这不起作用,也不能使用没有转义的直管。添加括号没有区别。
$ echo 'cat
dog
pear
banana
cat
dog' | sed 's/cat|dog/Bear/g'
cat
dog
pear
banana
cat
dog
$ echo 'cat
dog
pear
banana
cat
dog' | sed 's/cat\|dog/Bear/g'
cat
dog
pear
banana
cat
dog
Run Code Online (Sandbox Code Playgroud)
Mic*_*mer 57
默认情况下sed
使用POSIX 基本正则表达式,其中不包括|
交替运算符。您可以将其切换为使用Extended Regular Expressions,其中确实包括|
交替-E
(或-r
在某些实现的某些旧版本中)。您可以使用:
echo 'cat dog pear banana cat dog' | sed -E -e 's/cat|dog/Bear/g'
Run Code Online (Sandbox Code Playgroud)
它将在兼容的系统上工作。(-e
可选地标记 sed 脚本本身 - 您可以省略它,它只是防止某些类型的错误)
可移植到非常旧的sed
s 很复杂,但如果需要,您也可以切换到awk
它,它在任何地方都使用 ERE。
Nid*_*dal 12
发生这种情况是因为它(a|b)
是一个扩展的正则表达式,而不是一个基本的正则表达式。使用-E
选项来处理这个问题。
echo 'cat
dog
pear
banana
cat
dog'|sed -E 's/cat|dog/Bear/g'
Run Code Online (Sandbox Code Playgroud)
从sed
手册页:
Run Code Online (Sandbox Code Playgroud)-E Interpret regular expressions as extended (modern) regular expressions rather than basic regular expressions (BRE's).
请注意,这-r
是同一件事的另一个标志,但-E
更具可移植性,甚至会出现在下一版本的 POSIX 规范中。
mik*_*erv 10
执行此操作的可移植方式 - 也是更有效的方式 - 是使用地址。你可以这样做:
printf %s\\n cat dog pear banana cat dog |
sed -e '/cat/!{/dog/!b' -e '};cBear'
Run Code Online (Sandbox Code Playgroud)
这样,如果该行不包含字符串cat并且不包含字符串dog sed
b
ranches 退出脚本,则自动打印其当前行并拉入下一行以开始下一个循环。因此它不会执行下一条指令——在这个例子中,它c
挂起整行来读取Bear,但它可以做任何事情。
可能还值得注意的是!b
,该sed
命令中的后面的任何语句只能匹配包含字符串dog
或的行cat
- 因此您可以执行进一步的测试而不会匹配不匹配的行 - 这意味着您现在可以应用规则只有一个或另一个。
但那是接下来。以下是上述命令的输出:
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
Run Code Online (Sandbox Code Playgroud)
您还可以使用反向引用可移植地实现查找表。
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ cat dog /;x
};G;s/^\(.*\)\n.* \1 .*/Bear/;P;d'
Run Code Online (Sandbox Code Playgroud)
为这个简单的示例案例进行设置需要做更多的工作,但从sed
长远来看,它可以使脚本更加灵活。
在第一行中,我x
更改了保持空间和模式空间,然后在将它们改回之前将字符串<space>
cat <space>
dog<space>
插入保持空间x
。
从那时起,在接下来的每一行中,我都会G
将空格附加到模式空间,然后检查从行首到我刚刚在末尾添加的换行符之间的所有字符是否与后面由空格包围的字符串匹配。如果是这样,我用Bear替换整个批次,如果不是,则不会造成任何伤害,因为我接下来P
只打印模式空间中第一个出现的换行符,然后将d
其全部删除。
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
Run Code Online (Sandbox Code Playgroud)
当我说灵活时,我是认真的。这是更换猫与BrownBear和狗与BlackBear:
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ 1cat Brown 2dog Black /;x
};G;s/^\(.*\)\n.* [0-9]\1 \([^ ]*\) .*/\2Bear/;P;d'
###OUTPUT###
BrownBear
BlackBear
pear
banana
BrownBear
BlackBear
Run Code Online (Sandbox Code Playgroud)
当然,您可以对查找表的内容进行大量扩展——我从Greg Ubben关于这个主题的usenet 电子邮件中获得了这个想法,当时他在 90 年代描述了他如何用一个sed s///
语句构建一个粗略的计算器。