一致する単語が単語全体を構成する場合にのみ、どのように検索して置き換えることができますか?

一致する単語が単語全体を構成する場合にのみ、どのように検索して置き換えることができますか?

私のスクリプトは次のとおりです

n="y"
while [ "{n}" = "y" ]
if [ $n == "n" ];
then
  break;
fi
echo "n is $n"
do
        read -p "Enter the word to find = " word
        read -p "Enter word to replace = " replace
        echo "$word n $replace"
        #sed -i r.text.bak 's/$word/$replace/g' r.txt
        sed -i "s/$word/$replace/g" "test.txt"
echo "do you have further replacement? n or y"
read temp
n=$temp
done

私の問題は、部分一致も置き換えることです。たとえば、次の行の場合:

1.1.1.14 1.1.1.14567

私は次のような結果を得ます。

1.1.1.3  1.1.1.3567

しかし、私は次のことを楽しみにしています。

1.1.1.3 1.1.1.14567

この問題をどのように解決できますか?

答え1

完全な単語だけが一致するように正規表現を作成する必要があります。 GNUを使用すると、単語の境界で一致するものを使用sedできます。\b

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

常にスペースがあることがわかっている場合は、スペースを追加できます。

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

今スクリプトにもいくつかの問題があります。あなたのif ... break主張は役に立たない。彼らはwhileすでに問題に取り組んでいます。必要なものは次のとおりです。

#!/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

答え2

スクリプトで次の行を置き換えます。

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

答え3

ここではperl

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

sed(GNUではありません)正規表現で処理されるのを防ぐために必要な機能はsedありません。ほとんどの実装はこれをサポートしていません(または他の構文でサポートしています)。\Q\E$wordsed-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前後に空白以外の文字がない場合は一致します。 (戻る/前方演算子を使用し(?<!)(?!)否定します)。

デフォルトではperlASCII文字が使用されます。例えば、言葉文字は、_a-zA-Z0-9拡張Unicode間隔文字の個々のバイトと\b\Q1.2.3\E\b一致し1.2.3é\S一致します。非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é

答え4

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

sedはメタ文字もサポートしています\s

はい

var=world

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

結果

hello...

(\s|$)行はスペースの代わりに単語と行末文字で終わることができるため、パターンを入れる必要があります。

関連情報