일치하는 단어가 전체 단어를 구성하는 경우에만 어떻게 찾아서 바꿀 수 있습니까?

일치하는 단어가 전체 단어를 구성하는 경우에만 어떻게 찾아서 바꿀 수 있습니까?

내 스크립트는 다음과 같습니다

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확장 된 유니코드 간격 문자의 개별 바이트와 \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|$)줄은 공백 대신 단어와 줄 끝 문자로 끝날 수 있으므로 패턴을 넣어야 합니다.

관련 정보