Это довольно неудобно делать в sed, но вот версия, которая может работать, при условии, что есть один символ (я выбрал %
), который никогда не появится на входе. Символ используется для маркировки.
Допустим, у вас есть текстовый файл с именем words
со следующим содержимым:
Will He beat Sit Down Boy Oh Not now Latch Wi, Qq or Spat? GNU Hurd, protocols on GNU Mach. The Hurd versus Unix.
Следующий скрипт bash
сделает эту работу:
cat words
sed 's/ [A-Z][A-Za-z]*[A-Za-z]\{2\}/%&/g' words|tee a
sed 's/\([.!?]\)%/\1/g' a|tee b
sed 's/% [A-Za-z]*\([A-Za-z]\{2\}\)/ Derp\1/g' b|tee c
Вывод вышеупомянутого будет (я разделил каждую новую строку):
Will He beat Sit Down Boy Oh Not now Latch Wi, Qq or Spat? GNU Hurd, protocols on GNU Mach. The Hurd versus Unix.
Will He beat% Sit% Down% Boy Oh% Not now% Latch Wi, Qq or% Spat?% GNU% Hurd, protocols on% GNU% Mach.% The% Hurd versus% Unix.
Will He beat% Sit% Down% Boy Oh% Not now% Latch Wi, Qq or% Spat? GNU% Hurd, protocols on% GNU% Mach. The% Hurd versus% Unix.
Will He beat Derpit Derpwn Derpoy Oh Derpot now Derpch Wi, Qq or Derpat? GNU Derprd, protocols on DerpNU Derpch. The Derprd versus Derpix.
Вот как это работает:
- Первая строка просто печатает файл, поэтому вы видите начальную позицию.
- Во второй строке отмечены все заглавные слова, начинающиеся с пробела и длиной более 2 символов с
%
. Таким образом, он, например, помечает Latch
как % Latch
. Запишите пробел, я назову это пробел-слово.
- Третья строка удалит метку из всех пробелов, которым предшествует символ, заканчивающий предложение (для простоты я выбрал только
.
, !
Или ?
- вы можете добавить другие, например )
или такие, если это необходимо)
- Третья строка будет выполнять фактическое преобразование
Derp
- то есть заменить все пробел-слова, отмеченные %
DerpXX
, где XX
- два последних символа этого пробела.
Обратите внимание, что есть технические аспекты, которые не были рассмотрены здесь, такие как:
- Это будет работать только для слов США ASCII (например, не будет работать для всех французских слов, таких как
Être
)
- Возможно, следует рассмотреть другие символы (например, считается ли «
Oceans
в "Oceans Eleven"
словом, хотя оно имеет "
впереди»?)
- Не будет работать с пробелами без пробелов (например, вкладки)
и так далее.
Чтобы сделать его одним из сценариев sed
, просто объедините:
sed '
s/ [A-Z][A-Za-z]*[A-Za-z]\{2\}/%&/g
s/\([.!?]\)%/\1/g
s/% [A-Za-z]*\([A-Za-z]\{2\}\)/ Derp\1/g
' words
Очевидно, что в реальном мире я бы не использовал sed
для выполнения подобных задач. Опять же, у меня, вероятно, не будет таких задач, как это ... :)