2

Я пытаюсь создать команду sed, которая использует местоимение I в текстовом файле. Например, «я люблю собак». должно быть "я люблю собак". Пока что у меня есть:

sed 's/ i / I /g'

Это не работает в ряде разных сценариев. Например, если есть пунктуация вокруг i.

Вот список сценариев, о которых я думал, что команда должна быть в состоянии обработать:

  • Есть несколько « я » в одной строке текста. Я думаю, что это можно решить, просто поставив флаг g в конце.
  • « Я » имеет пунктуацию вокруг него. Например, запятая или точка после нее, или кавычка или скобка до или после нее.
  • « I » - это первый или последний символ в строке. Это означает, что вы не можете просто проверить пробел или пунктуацию вокруг него.
  • Любые обычные « я » в слове остаются одни. Например , «е я реф я ghter» не должна превращаться в «е я реф я ghter».

2 ответа2

5

Предполагая, что вы используете GNU sed, одним из способов является

sed 's/\([[:space:]]\|[[:punct:]]\)i\([[:space:]]\|[[:punct:]]\)/\1I\2/g'

или что-то типа того. Это все еще оставляет случай строки, начинающейся с «я люблю собак», потому что нет места перед местоимением. Один из способов исправить это

sed 's/\(^\|[[:space:]]\|[[:punct:]]\)i\([[:space:]]\|[[:punct:]]\)/\1I\2/g'

Это все еще оставляет случай, когда у вас есть последовательный "я", как в "II", но я не могу думать ни о какой причине, почему это произошло бы в английском тексте, за исключением случаев, когда кто-то по ошибке написал "II сэр", когда правильная фраза "да" да сэр'.

Есть также неровные края, если вы также используете строчные римские цифры. Сценарий sed не сможет определить, является ли «i» местоимением или римской цифрой, но на самом деле нет хорошего решения для этого.

2

Простое решение (с помощью GNU sed):

sed 's/\bi\b/I/g'

Это в основном та же концепция, что и в другом ответе - заменить «я» на «я», когда оно не является частью более крупного слова.  \b похоже, не упоминается на странице руководства sed, но это объясняется в руководстве GNU sed:

\b

    Соответствует границе слова; то есть совпадает, если символ слева является символом «слова», а символ справа - символом, не являющимся словом, или наоборот.
$ echo "abc %-= def." | sed 's/\b/X/g'
XabcX %-= XdefX.

Даже в руководстве явно не сказано (но пример показывает), что \b соответствует началу и концу строки.  Это не соответствует ни одному персонажу; он соответствует пустой строке, которая появляется между символом «слово» и символом «не слово» (в любом порядке) или в начале и конце строки (например, ^ и $).  Поэтому нам не нужно беспокоиться о захвате (с \(\)) символов, которые им соответствуют, и замене их на \1 и \2 .  И, поскольку \b не совпадает ни с одним символом, эта команда работает с i i (изменяя его на I I).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .