Как я могу найти и заменить, только если соответствие формирует целое слово?

Не уверенный, что они имеют в виду, учитывая, что

  • сокеты произошли в BSDs и в 4.3BSD, документация ясно указывает, что разрешение записи требуется для a connect().
  • На Linux также, читайте, разрешение не требуется, только запишите.

POSIX, кажется, не требует connect() перестать работать, если файл сокета не является записываемым, но явно позволяет его (connect может перестать работать [...], если именованный сокет не является записываемым). Это "может" предполагать, что могут быть действительно системы, которые не соблюдают полномочия, но я сомневаюсь, что они были бы полученным BSD.

5
14.02.2015, 15:18
4 ответа

Вам нужно написать ваше регулярное выражение таким образом, чтобы соответствовать только целым словам. С GNU SED , вы можете использовать \ b , которые совпадают на границах слов:

sed -i "s/\b$word\b/$replace/g"

Если вы знаете, что там всегда будет место, вы могли бы просто добавить место:

sed -i "s/ $word /$replace/g"

Теперь есть также некоторые проблемы с вашим сценарием. Ваш Если ... Break Заявление бесполезно, в то время как уже заботится об этом. Все, что вам нужно, это:

#!/usr/bin/env bash
n="y"
while [ "$n" = "y" ]
do
    echo "n is $n"
    read -p "Enter the word to find = " word
    read -p "Enter word to replace = " replace
    echo "$word n $replace"
    sed -i "s/\b$word\b/$replace/g" test.txt
    echo "do you have further replacement? n or y"
    read temp
    n="$temp"
done
7
27.01.2020, 20:38
sed -i "s/\s$word\s/$replace/g" "test.txt"

SED также поддерживает примеру Metacharacter \ S

var=world

echo "hello world"|sed -r "s/\s$var(\s|$)/.../g"

Результаты

hello...

Примечание. Это необходимо поставить (\ S | $) . Слово, за которым следует конец линии линий вместо пробела

-2
27.01.2020, 20:38

Замените в скрипте следующую строку

sed -i "s/$word/$replace/g" "test.txt"

на

sed -i "s/$\bword\b/$replace/g" test.txt

Пожалуйста, обратитесь к следующей ссылке. http://www.rexegg.com/regex-boundaries.html#wordboundary

1
27.01.2020, 20:38

Здесь я бы использовал perl .

WORD=$word REPLACE=$replace perl -pi -e '
  s/\b\Q$ENV{WORD}\E\b/$ENV{REPLACE}/g' file

sed (даже GNU sed ) не имеет эквивалента для \ Q \ E , который вам нужен здесь, чтобы $ word не использовалось как регулярное выражение. И большинство реализаций sed не поддерживают -i (или поддерживают его с другим синтаксисом) или \ b .

\ b соответствует переходу между словом и несловесным символом.

Таким образом, \ b \ Q1.1.2.3 \ E \ b все равно будет соответствовать в 1.1.2.3.4 как . - это не слово .

Вы также можете сделать:

WORD=$word REPLACE=$replace perl -pi -e '
  s/(?<!\S)\Q$ENV{WORD}\E(?!\S)/$ENV{REPLACE}/g' file

Чтобы найти соответствие $ word , если перед ним и за ним не стоит символ без пробелов. (с использованием операторов (? и (?!) отрицательного просмотра назад / вперед).

Обратите внимание, что perl по умолчанию будет работать с символами ASCII.Например, символ слова будет только _a-zA-Z0-9 ( \ b \ Q1.2.3 \ E \ b будет соответствовать в ] 1.2.3é и \ S будут соответствовать отдельным байтам символов расширенного интервала Unicode). Для данных, отличных от ASCII, вы, вероятно, захотите добавить параметр -CLSD в perl .

Некоторые примеры:

$ export WORD=1.1.1.3 REPLACE=REPLACE
$ printf '1.1.1.3-x 1.1.1.3\u2006 1.1.1.3.4 1.1.123 1.1.1.3\u20dd 1.1.1.3\ue9\n' > f
$ cat f
1.1.1.3-x 1.1.1.3  1.1.1.3.4 1.1.123 1.1.1.3⃝ 1.1.1.3é
$ perl -pe 's/\b\Q$ENV{WORD}\E\b/$ENV{REPLACE}/g' f
REPLACE-x REPLACE  REPLACE.4 1.1.123 REPLACE⃝ REPLACEé
$ perl -CLSD -pe 's/\b\Q$ENV{WORD}\E\b/$ENV{REPLACE}/g' f
REPLACE-x REPLACE  REPLACE.4 1.1.123 1.1.1.3⃝ 1.1.1.3é
$ perl -pe 's/(?<!\S)\Q$ENV{WORD}\E(?!\S)/$ENV{REPLACE}/g' f
1.1.1.3-x 1.1.1.3  1.1.1.3.4 1.1.123 1.1.1.3⃝ 1.1.1.3é
$ perl -CLSD -pe 's/(?<!\S)\Q$ENV{WORD}\E(?!\S)/$ENV{REPLACE}/g' f
1.1.1.3-x REPLACE  1.1.1.3.4 1.1.123 1.1.1.3⃝ 1.1.1.3é

$ sed "s/\b$WORD\b/$REPLACE/g" f
REPLACE-x REPLACE  REPLACE.4 REPLACE REPLACE⃝ 1.1.1.3é
0
27.01.2020, 20:38

Теги

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