Sed命令奇怪的事情

时间:2017-01-12 18:54:07

标签: regex sed

有人可以向我解释这个命令的作用吗?

sed 's/\|/replacement/g' somefile

我无法理解为什么他会替换任何字符。

1 个答案:

答案 0 :(得分:2)

您在哪个平台上使用哪个版本的sed?某些版本的sed(例如GNU sed)将\|视为激活'或'条件,在这种情况下,您匹配空字符串或空字符串,匹配于输入中的所有点(每个字符之间),为您提供声明的结果。

sed的其他版本(例如BSD sed,也可以在macOS Sierra等上找到)更紧密地遵循sed的POSIX标准,而不是\|进入'或'状态。

如果您添加-E-r以启用“扩展正则表达式”,则\|将成为文字管道。如果要匹配管道符号,则不需要(不应该)执行任何特殊操作。默认情况下,sed使用稍微扩展的POSIX基本正则表达式版本或BRE。

tester.sh

使用-e选项是不必要的,但我这样做是因为它也是明确的;使用-n选项可避免重复输出;使用l命令明确地列出输出 - sed在输出行的末尾添加$;使用"$rx"周围的引号至关重要;在"$sed"周围使用引号是好的,但对于使用的路径不是必需的;并且在$opt周围不使用引号也是至关重要的,因为它确保当字符串为空时没有选项存在,但在另一次迭代时安全地扩展到-E

for sed in /usr/bin/sed /opt/gnu/bin/sed
do
    for rx in 's/|/ /g;l' 's/\|/ /g;l' 
    do
        for opt in '' '-E'
        do
            (set -x; echo "blablabla|gibberish" | "$sed" $opt -n -e "$rx")
        done
    done
done

输出

$ bash tester.sh
+ echo 'blablabla|gibberish'
+ /usr/bin/sed -n -e 's/|/ /g;l'
blablabla gibberish$
+ echo 'blablabla|gibberish'
+ /usr/bin/sed -E -n -e 's/|/ /g;l'
sed: 1: "s/|/ /g;l
": RE error: empty (sub)expression
+ echo 'blablabla|gibberish'
+ /usr/bin/sed -n -e 's/\|/ /g;l'
blablabla gibberish$
+ echo 'blablabla|gibberish'
+ /usr/bin/sed -E -n -e 's/\|/ /g;l'
blablabla gibberish$
+ echo 'blablabla|gibberish'
+ /opt/gnu/bin/sed -n -e 's/|/ /g;l'
blablabla gibberish$
+ echo 'blablabla|gibberish'
+ /opt/gnu/bin/sed -E -n -e 's/|/ /g;l'
 b l a b l a b l a | g i b b e r i s h $
+ echo 'blablabla|gibberish'
+ /opt/gnu/bin/sed -n -e 's/\|/ /g;l'
 b l a b l a b l a | g i b b e r i s h $
+ echo 'blablabla|gibberish'
+ /opt/gnu/bin/sed -E -n -e 's/\|/ /g;l'
blablabla gibberish$
$

在我的机器上,/usr/bin/sed是BSD sed,而(惊讶)/opt/gnu/bun/sed是GNU sed。 BSD版本不喜欢sed -E -n -e 's/|/ /g;l'的两个空模式。