Bu eski bir sorudur, ancak buradaki cevapların hiçbiri, s/from/to/çok fazla ayrıntı dışında operasyonları tartışmaz .
Bir sedifadenin 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,4ve eylem , dsilme 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 fooile değiştirir ( adres aralıktır ve eylem , ikame komutudur ).barick/ick/,$ss/foo/bar/
Bu bağlamda, ickbir 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 sedyalnı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, $variabledizeyi 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.