Решения sed
в Самый длинный общий префикс двух строк в bash работают только с 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
команда в последней строкеБольшинство версий
sed
закрываются, ничего не печатая, когда командаN
выдается в последней строке файла.GNU sed
печатает пространство шаблона перед выходом, если, конечно, не был указан командный переключатель-n
.
Обратите внимание, что я не использовал sed -E
, потому что macOS sed -E
не поддерживает обратную ссылку \N
в части шаблона команды s/pattern/replace/
.
С GNU-седом:
$ echo foofoo | gsed -E 's/(foo)\1/bar/'
bar
С macOS sed:
$ echo foofoo | sed -E 's/(foo)\1/bar/'
foofoo
Нашел это в другом ответе :
sed -e '1{h;d;}' -e 'G;s/\(.*\).*\n\1.*/\1/;h;$!d'
Обратите внимание, что это не работает, когда ввод включает только одну строку. Можно легко исправить, удалив часть 1d
:
sed -e '1h;G;s/^\(.*\).*\n\1.*/\1/;h;$!d'