【发布时间】:2020-12-11 04:24:44
【问题描述】:
Longest common prefix of two strings in bash 中的sed 解决方案仅适用于 GNU sed。我想要一个更便携的 sed 解决方案(例如,用于 BSD/macOS 的 sed,Busybox sed)。
【问题讨论】:
Longest common prefix of two strings in bash 中的sed 解决方案仅适用于 GNU sed。我想要一个更便携的 sed 解决方案(例如,用于 BSD/macOS 的 sed,Busybox sed)。
【问题讨论】:
以下解决方案已使用 GNU sed、macOS (10.15) sed 和 busybox (v1.29) sed 进行测试。
$ printf '%s\n' a ab abc | sed -e '$q;N;s/^\(.*\).*\n\1.*$/\1/;h;G;D'
a
$ printf '%s\n' a b c | sed -e '$q;N;s/^\(.*\).*\n\1.*$/\1/;h;G;D'
$
在有很多字符串时更高效,尤其是在根本没有公共前缀的情况下(注意 ..* 部分,这与之前的解决方案不同):
$ printf '%s\n' a ab abc | sed -ne :L -e '$p;N;s/^\(..*\).*\n\1.*/\1/;tL' -e q
a
$ printf '%s\n' a b c | sed -ne :L -e '$p;N;s/^\(..*\).*\n\1.*/\1/;tL' -e q
$
$q
根据 GNU sed 手册 (info sed):
N命令在最后一行当在文件的最后一行发出
N命令时,大多数版本的sed退出而不打印任何内容。GNU sed在退出之前打印模式空间,当然除非指定了-n命令开关。
请注意,我没有使用sed -E,因为macOS sed 的-E 不支持s/pattern/replace/ 命令的模式 字符串中的\N 反向引用。
$ # with GNU sed:
$ echo foofoo | gsed -E 's/(foo)\1/bar/'
bar
$
$ # with macOS's own sed:
$ echo foofoo | sed -E 's/(foo)\1/bar/'
foofoo
$
在另一个 answer 中找到这个:
sed -e '1{h;d;}' -e 'G;s/\(.*\).*\n\1.*/\1/;h;$!d'
请注意,只有一行时它不起作用。可以通过删除1d 部分轻松修复:
sed -e '1h;G;s/^\(.*\).*\n\1.*/\1/;h;$!d'
【讨论】: