ค้นหาทั้งคำและแทนที่


120

ฉันจะค้นหาและแทนที่ทั้งคำโดยใช้ sed ได้อย่างไร

การทำ

sed -i 's/[oldtext]/[newtext]/g' <file> 

จะแทนที่การจับคู่บางส่วน[oldtext]ที่ฉันไม่ต้องการให้ทำ

คำตอบ:


164

\ b ในนิพจน์ทั่วไปตรงกับขอบเขตของคำ (เช่นตำแหน่งระหว่างอักขระคำแรกและอักขระที่ไม่ใช่คำ):

$ echo "bar embarassment" | sed "s/\bbar\b/no bar/g"
no bar embarassment


@OlegMazko ฉันยังมองหาวิธีที่ยอมรับได้สำหรับ posix เพื่อใช้ในกลุ่มและสิ่งที่ได้ผลสำหรับฉันคือ s / \ <7 // g ฉันพยายามลบ 7 ที่ขึ้นต้นคำในรหัสของฉัน ลิงก์นี้โดยเฉพาะโซลูชันของ JP นำฉันไปสู่คำตอบ: stackoverflow.com/questions/3864467/… (ไม่สามารถรับ markdown เพื่อฝังเหมือนของคุณด้วยเหตุผลบางประการ)
jimh

ขอบคุณฉันแทบบ้าที่พยายามแทนที่คำว่า "และ" เพื่อ\band\bช่วยให้วันนี้ :)
MitchellK

145

ใน Mac OS X ไวยากรณ์ regex เหล่านี้ไม่สามารถใช้งานได้ในsedสำหรับการจับคู่คำ

  • \bmyWord\b
  • \<myWord\>

ฟังฉันตอนนี้และเชื่อฉันในภายหลังไวยากรณ์ที่น่าเกลียดนี้คือสิ่งที่คุณต้องใช้:

  • /[[:<:]]myWord[[:>:]]/

ตัวอย่างเช่นในการแทนที่mintด้วยmintyสำหรับทั้งคำเท่านั้น:

  • sed "s/[[:<:]]mint[[:>:]]/minty/g"

ที่มา: re_format man page


19
เพียงติดตั้ง GNU sed(และเครื่องมือ GNU อื่น ๆ ) ผ่าน MacPorts หรือ Homebrew และตรวจสอบให้แน่ใจว่ามาก่อนในPATHไฟล์. เป็นไปได้ที่จะทำให้ Mac ใช้งานได้จริง
Jim Stewart

9
@JimStewart วิธีที่ยอดเยี่ยมในการทำลายเครื่องมือมากมายที่ถือว่า 'เมื่ออยู่บน OS X ให้ทำเหมือน OS Xers' ที่กล่าวว่าฉันสามารถแนะนำได้อย่างแน่นอนbrew install coreutilsซึ่งนำหน้าเครื่องมือ gnu ทั้งหมด
ELLIOTTCABLE

16
brew install gnu-sedใช้gsed
k107

coreutils ชงน่ากลัว มีแพ็คเกจการชงอื่น ๆ ที่ติดตั้งคำสั่งเวอร์ชัน gnu ทั้งหมดหรือฉันต้องติดตั้งส่วนที่เหลือทีละรายการหรือไม่?
ckot

2
ใช้ Perl perl -pe 's|\bone\b|two|g'มักจะเป็นทางออกที่ดีกว่า: ทำงานได้อย่างเสถียรในขณะที่ sed ล้มเหลวที่นี่และที่นั่น
Pavel Vlasov

13

ใช้\bสำหรับขอบเขตคำ:

sed -i 's/\boldtext\b/newtext/g' <file>

3
ระมัดระวังกับ[]: ->o,l [newtext],[newtext]เห็นได้ชัดว่าคุณหมายถึง sed -i 's/\boldtext\b/newtext/g'
JJoao

7

ในเครื่องของฉันการขีดฆ่าคำด้วย " \b" (โดยไม่มีเครื่องหมายอัญประกาศ) ใช้ไม่ได้ วิธีแก้ปัญหาคือใช้ " \<" สำหรับตัวคั่นเริ่มต้นและ " \>" สำหรับการสิ้นสุดตัวคั่น

เพื่ออธิบายด้วยตัวอย่างของJoakim Lundberg :

$ echo "bar embarassment" | sed "s/\<bar\>/no bar/g"
no bar embarassment

2

ในคำสั่งเชลล์:

echo "bar embarassment" | sed "s/\bbar\b/no bar/g" 

หรือ:

echo "bar embarassment" | sed "s/\<bar\>/no bar/g"

แต่ถ้าคุณอยู่ในกลุ่มคุณสามารถใช้ได้ในภายหลังเท่านั้น:

:% s/\<old\>/new/g

-1
$ echo "bar embarassment"|awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1'
no bar embarassment

OP ระบุชัดแจ้ง "ใช้ sed"
ndemou

นี่คือการแยกส่วนจัดการ - เข้าร่วมไม่ใช่การแทนที่ที่บริสุทธิ์ นี้ทรุดฮวบลงช่องว่างหลายเป็นหนึ่งและทิ้ง / ช่องว่างใด ๆ ต่อท้ายชั้นนำเช่นให้echo " bar embarassment " | awk '{for(o=1;o<=NF;o++)if($o=="bar")$o="no bar"}1' | cat -E no bar embarassment$
musiphil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.