Bu eski bir sorudur, ancak buradaki cevapların hiçbiri, s/from/to/
çok fazla ayrıntı dışında operasyonları tartışmaz .
Bir sed
ifadenin genel şekli
*address* *action*
burada adres bir normal ifade aralığı veya bir satır numarası aralığı olabilir (veya boş, bu durumda eylem her giriş satırına uygulanır). Yani mesela
sed '1,4d' file
1'den 4'e kadar olan satırları silecektir ( adres , satır numarası aralığıdır 1,4
ve eylem , d
silme komutudur); ve
sed '/ick/,$s/foo/bar/' file
, normal ifadedeki ilk eşleşme ile dosyanın sonu arasındaki herhangi bir satırda ilk geçtiği yeri foo
ile değiştirir ( adres aralıktır ve eylem , ikame komutudur ).bar
ick
/ick/,$
s
s/foo/bar/
Bu bağlamda, ick
bir değişkenden geldiyse,
sed "/$variable/,\$s/foo/bar/"
(Kabuğun değişkeni enterpolasyon yapabilmesi için tek yerine çift tırnak kullanıldığına ve dolar işaretini çift tırnak içine alma gerekliliğine dikkat edin) ancak değişken bir bölü çizgi içeriyorsa, sözdizimi hatası alırsınız. (Kabuk değişkeni genişletir, sonra elde edilen dizgeyi iletir sed
; bu nedenle sed
yalnızca değişmez metni görür - kabuğun değişkenleri hakkında hiçbir kavramı yoktur.)
Çözüm, farklı bir sınırlayıcı kullanmaktır (tabii ki değişkenin değerinde bulunamayan bir karakteri kullanabilmeniz gerekir), ancak s%foo%bar%
durumdan farklı olarak, farklı bir sınırlayıcı kullanmak istiyorsanız, sınırlayıcıdan önce bir ters eğik çizgiye de ihtiyacınız vardır. varsayılandan daha fazla sınırlayıcı /
:
sed "\\%$variable%,\$s/foo/bar/" file
(tek tırnak içinde, tek bir ters eğik çizgi yeterli olacaktır); veya değerdeki her bölü çizgisinden ayrı ayrı kaçabilirsiniz. Bu belirli sözdizimi yalnızca Bash'tir:
sed "/${variable//\//\\/}/,\$s/foo/bar/" file
veya farklı bir kabuk kullanıyorsanız, deneyin
escaped=$(echo "$variable" | sed 's%/%\\/%g')
sed "s/$escaped/,\$s/foo/bar/" file
Netlik sağlamak için, $variable
dizeyi içeriyorsa 1/2
, yukarıdaki komutlar şuna eşdeğer olacaktır:
sed '\%1/2%,$s/foo/bar/' file
ilk durumda ve
sed '/1\/2/,$s/foo/bar/' file
saniyede.