Это работает с GNU sed, по крайней мере для примера ввода:
$ sed -Ez ':a;s/(\<\S+)(\s+)\1\s+/\1\2/g;ta' infile
This is a text file and is littered with duplicate words
on one or more lines
Опция -E
только для того, чтобы избежать необходимости избегать скобок группы захвата и +
квантификаторов.
-z
обрабатывает ввод как разделенный нулевым байтом, т. Е. Как одну строку.
Команда затем структурируется как
:a # label
s///g # substitution
ta # jump to label if substitution did something
И подстановка такая:
s/(\<\S+)(\s+)\1\s+/\1\2/g
- Первая группа захвата:
(\<\S+)
- полное слово (начало границы слова, один или несколько непробельных символов - Вторая группа захвата:
(\s+)
- любаяколичество пробелов после этого первого слова \1\s+
- снова первое слово плюс любые пробелы после него
Это сохраняет пробел после первого слова и удаляет пробел после дубликата.
Обратите внимание, что -E
, -z
, \<
, \S
и \s
являются расширениями GNU для POSIX sed.