Это работает (как и решение от potong ):
sed -e ': loop' \
-e 's/\([a-z]*\)\([a-z]\)\([a-z]*\) \([a-z]*\2[a-z]*\)/\1\3 \4/' \
-e 't loop' \
-e 's/ .*//' \
"$@"
Первая строка устанавливает метку. Третья строка разветвляется на метку, если с момента чтения строки произошел успешный заменитель, и при последнем выполнении t
, что создает цикл, в то время как команда замещения находит что-то для выполнения. Последняя строка удаляет слово после пробела после завершения цикла.
Теперь все глаза сосредоточены на регулярных выражениях. Основная идея заключается в том, что вы можете искать повтор запомненного шаблона позже в строке, используя \n
, где n
- это цифра. Первая часть регулярного выражения разбивает строку на 5 частей. Первая часть - это (возможно, пустая) последовательность букв, которые не интересны; второе - отдельное письмо, которое интересно; третья - другая (возможно, пустая) последовательность букв, которые не интересны; четвертый - это пробел, отделяющий первое слово от второго. Сама последняя часть может быть разделена на 3 части, хотя все они сгруппированы в одно выражение захвата. Он состоит из последовательности из нуля или более неинтересных букв, повторения интересной буквы из первого слова в строке (\2
) и другой последовательности из нуля или более неинтересных букв.
Строка замены содержит части первого слова до и после, плюс пробел и второе слово.
В комбинации он находит каждую из букв c
, o
и t
по очереди, исключая их из первого слова и оставляя их одних во втором.
Условное ветвление в sed
сложно использовать, но иногда оно может дать результат. Когда ваши руки связаны таким назначением, это делает решение выполнимым.
$ al 'computer cost' 'encyclopedia brittanica' 'security privacy' |
> sed -e ': loop; s/\([a-z]*\)\([a-z]\)\([a-z]*\) \([a-z]*\2[a-z]*\)/\1\3 \4/; t loop'
mpuer
eyloped
seut
$
al
просто перечисляет свои аргументы по одному на строку - отсюда и мнемонический список аргументов:
#include <stdio.h>
int main(int argc, char **argv)
{
while (*++argv)
puts(*argv);
return 0;
}
Решение Потонга по сути эквивалентно моей версии Code Golf:
sed ':a;s/\(.\)\(.* .*\1.*\)/\2/;ta;s/ .*//'
Он использует ту же общую технику, что и моя, но упрощает регулярное выражение. Одним из упрощений является использование .
(любой символ) вместо [a-z]
(любая буква). Другой - осознать, что ведущая модель не имеет значения; он останется один. Последнее состоит в том, чтобы сгруппировать хвост первого слова со всем вторым. Оглядываясь назад, я мог (должен?) Добавить к своему шаблону привязку ^
. Ярлык Потонга просто a
.