내 스크립트는 다음과 같습니다
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
$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
일치합니다. 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|$)
줄은 공백 대신 단어와 줄 끝 문자로 끝날 수 있으므로 패턴을 넣어야 합니다.