Sed Script для заглавных букв "I" в текстовом файле

399
nickeb96

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

sed 's/ i / I /g' 

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

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

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

2 ответа на вопрос

5
user10354138

Предполагая, что вы используете 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» местоимением или римской цифрой, но на самом деле нет хорошего решения для этого.

Обходной путь для случая `ii` - применить преобразование дважды. Это может быть достигнуто одной командой: `sed -e 's…' -e 's…'`. Kamil Maciorowski 5 лет назад 0
Я пытался избегать делать что-то дважды, но я полагаю, что если толчок придет, это единственный путь. user10354138 5 лет назад 0
2
G-Man

Простое решение (с помощью 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).

Похожие вопросы