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).
1 Answers
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
$
Regarding $q in the first solution
According to GNU sed manual (info sed):
Ncommand on the last lineMost versions of
sedexit without printing anything when theNcommand is issued on the last line of a file.GNU sedprints pattern space before exiting unless of course the-ncommand 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/' barWith macOS sed:
$ echo foofoo | sed -E 's/(foo)\1/bar/' foofoo
UPDATE (2021-04-26):
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'
- 19,215
- 5
- 38
- 56