Reputation: 20698
The sed
solutions in Longest common prefix of two strings in bash only work with GNU sed
. I'd like a more portable sed
solution (e.g. for BSD/macOS sed
, Busybox sed
).
Upvotes: 2
Views: 424
Reputation: 20698
The following solutions are tested with GNU sed, macOS (10.15) sed and 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'
$
To be more efficient when there are many strings especially when there's no common prefix at all (note the ..*
part which is different from the previous solution):
$ 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
in the first solutionAccording to GNU sed manual (info sed
):
N
command on the last lineMost versions of
sed
exit without printing anything when theN
command is issued on the last line of a file.GNU sed
prints pattern space before exiting unless of course the-n
command switch has been specified.
Note that I did not use sed -E
because macOS' sed -E
does not support \N
back-reference in s/pattern/replace/
command's pattern part.
With GNU sed:
$ echo foofoo | gsed -E 's/(foo)\1/bar/'
bar
With macOS sed:
$ echo foofoo | sed -E 's/(foo)\1/bar/'
foofoo
Found this in another answer :
sed -e '1{h;d;}' -e 'G;s/\(.*\).*\n\1.*/\1/;h;$!d'
Note that it does not work when the input includes only one line. Can be easily fixed by removing the 1d
part:
sed -e '1h;G;s/^\(.*\).*\n\1.*/\1/;h;$!d'
Upvotes: 5