Не уверенный, что они имеют в виду, учитывая, что
connect()
.POSIX, кажется, не требует connect()
перестать работать, если файл сокета не является записываемым, но явно позволяет его (connect
может перестать работать [...], если именованный сокет не является записываемым). Это "может" предполагать, что могут быть действительно системы, которые не соблюдают полномочия, но я сомневаюсь, что они были бы полученным BSD.
Вам нужно написать ваше регулярное выражение таким образом, чтобы соответствовать только целым словам. С 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
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 | $)
. Слово, за которым следует конец линии линий вместо пробела
Замените в скрипте следующую строку
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
Здесь я бы использовал 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é