"Suzi ve Marry'i seviyorum" var ve "Suzi" yi "Sara" olarak değiştirmek istiyorum.
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Sonuç şu şekilde olmalıdır:
firstString="I love Sara and Marry"
"Suzi ve Marry'i seviyorum" var ve "Suzi" yi "Sara" olarak değiştirmek istiyorum.
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
# do something...
Sonuç şu şekilde olmalıdır:
firstString="I love Sara and Marry"
Yanıtlar:
Bir desenin ilk tekrarlamasını belirli bir dizeyle değiştirmek için şunu kullanın :${parameter/pattern/string}
#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"
# prints 'I love Sara and Marry'
Tüm oluşumları değiştirmek için şunu kullanın :${parameter//pattern/string}
message='The secret code is 12345'
echo "${message//[0-9]/X}"
# prints 'The secret code is XXXXX'
(Bu belgelenmiştir Bash Reference Manual §3.5.3, "Kabuk Parametrelerinin" .)
Bu özelliğin POSIX tarafından belirtilmediğini unutmayın - bir Bash uzantısıdır - bu nedenle tüm Unix kabukları bunu uygulamaz. İlgili POSIX belgeleri için, bkz . Open Group Teknik Standart Temel Özellikleri, Sayı 7 , Shell & Utilities birimi, §2.6.2 "Parametre Genişletme" .
\n
bu bağlamda bir satırsonu değil kendini temsil ederdi. Bash'i test etmek için şu anda kullanışlı değilim, ama böyle bir şey yazabilmelisin $STRING="${STRING/$'\n'/<br />}"
. (Muhtemelen isteseniz de STRING//
- yerine tüm - yerineSTRING/
echo ${my string foo/foo/bar}
. İhtiyacınız olacakinput="my string foo"; echo ${input/foo/bar}
//
doğrudan bahsetmektense , " örüntü ' /
' ile başlıyorsa (bu doğru bile değil, çünkü bu cümlenin geri kalanı ekstraın /
aslında bir parçası olmadığını varsayar . - ama daha iyi bir kaynak bilmiyorum.
Bu tamamen bash string manipülasyonu ile yapılabilir:
first="I love Suzy and Mary"
second="Sara"
first=${first/Suzy/$second}
Bu sadece ilk olayın yerini alacaktır; hepsini değiştirmek için ilk eğik çizgiyi iki katına çıkarın:
first="Suzy, Suzy, Suzy"
second="Sara"
first=${first//Suzy/$second}
# first is now "Sara, Sara, Sara"
Dash için önceki tüm yayınlar çalışmıyor
POSIX sh
uyumlu çözüm:
result=$(echo "$firstString" | sed "s/Suzi/$secondString/")
result=$(echo $firstString | sed "s/Suzi/$secondString/g")
echo
argümanın etrafındaki eksik tırnakları da ekledim . Basit dizelerle alıntı yapmadan aldatıcı bir şekilde çalışır, ancak önemsiz olmayan herhangi bir giriş dizesini (düzensiz aralık, kabuk metakarakterleri, vb.)
bunu dene:
sed "s/Suzi/$secondString/g" <<<"$firstString"
sed
Dizeleri RegExp karakterlerine sahip olmaktan daha iyi bash kullanmak daha iyidir .
echo ${first_string/Suzi/$second_string}
Windows'a taşınabilir ve en azından Bash 3.1 kadar eski ile çalışır.
Kaçmak için endişelenmenize gerek olmadığını göstermek için şunu açalım:
/home/name/foo/bar
Bunun içine:
~/foo/bar
Ama sadece /home/name
başlangıçta ise. İhtiyacımız yok sed
!
Bash bize sihirli değişkenleri verdiğini göz önüne alındığında $PWD
ve $HOME
biz yapabilir:
echo "${PWD/#$HOME/\~}"
EDIT: Mark Haferkamp için alıntı / kaçış notu yorumlarında teşekkürler ~
. *
Değişkenin $HOME
eğik çizgileri nasıl içerdiğine dikkat edin, ancak bu hiçbir şeyi bozmadı.
İlave değerler: Gelişmiş Bash-Scripting Kılavuzu .
Kullanmak şartsa, her karakterden kaçtığınızdansed
emin olun .
sed
, pwd
özel $PS1
çalıştığımda her çalıştırıldığında yeni bir değişken tanımlamaktan kaçınmak için komutu kullanmamı engelledi. Bash, string değiştirme için bir komutun çıktısını kullanmak için sihirli değişkenlerden daha genel bir yol sunuyor mu? Kodunuza gelince, ~
Bash'in $ HOME'a genişletilmesini önlemek için kaçmak zorunda kaldım . Ayrıca, #
komutunuzdaki ne işe yarar?
~
": nasıl şeyler alıntı dikkat edin. Her zaman bir şeyler teklif etmeyi unutmayın! Ve bu sadece sihirli değişkenler için işe yaramaz: herhangi bir değişken bash içinde ikame, dize uzunluğu alma ve daha fazlasını yapabilir. $PS1
Hızlı çalıştığınız için tebrikler : $PROMPT_COMMAND
başka bir programlama dilinde daha rahatsanız ve derlenmiş bir istemi kodlamak istiyorsanız da ilginizi çekebilir .
echo "${PWD/#$HOME/~}"
değiştirmez benim . Değiştirme ile veya çalışır. Bunlardan herhangi biri başka bir dağıtımda Bash 4.2.53 üzerinde çalışır. Daha iyi uyumluluk için teklifinizi güncellemek veya kaçmak için lütfen gönderinizi güncelleyebilir misiniz ? Benim "sihirli değişkenler" sorumla kastettiğim şuydu: Bash'in değişken ikamesini, örneğin, önce değişken olarak kaydetmeden çıktısında kullanabilir miyim ? Kişisel gelince , bu karmaşık . $HOME
~
~
\~
'~'
~
uname
$PROMPT_COMMAND
Yarın Marry'yi sevmediğinize karar verirseniz, o da değiştirilebilir:
today=$(</tmp/lovers.txt)
tomorrow="${today//Suzi/Sara}"
echo "${tomorrow//Marry/Jesica}" > /tmp/lovers.txt
Sevgilinizi terk etmenin 50 yolu olmalı.
Yorum ekleyemediğim için. @ruaka Örneği daha okunabilir hale getirmek için şöyle yazın
full_string="I love Suzy and Mary"
search_string="Suzy"
replace_string="Sara"
my_string=${full_string/$search_string/$replace_string}
or
my_string=${full_string/Suzy/Sarah}
Saf POSIX aksine kabuk yöntemi, Roma Kazanovskyi 'ın sed
tabanlı cevap harici araçlara ihtiyacı, sadece kabuk kendi yerli parametre açılımları . Kodun bir satıra daha iyi uyması için uzun dosya adlarının en aza indirildiğini unutmayın:
f="I love Suzi and Marry"
s=Sara
t=Suzi
[ "${f%$t*}" != "$f" ] && f="${f%$t*}$s${f#*$t}"
echo "$f"
Çıktı:
I love Sara and Marry
Nasıl çalışır:
En Küçük Sonek Desenini Kaldır. "${f%$t*}"
döner " I love
" eki ise $t
" Suzi*
" içindedir $f
" ". I love
Suzi and Marry
Ama eğer t=Zelda
, o zaman "${f%$t*}"
hiçbir şey silmez ve " I love Suzi and Marry
" dizesinin tamamını döndürür .
Bu teste kullanılan $t
içindedir $f
ile [ "${f%$t*}" != "$f" ]
hangi değerlendirecek gerçek ise $f
dize içerir "Suzi*
" ve sahte değilse.
Test true değerini döndürürse , aradaki 2. " " dizesi ile " " En Küçük Sonek Desenini Kaldır ve ${f%$t*}
" I love
" En Küçük Önek Desenini Kaldır'ı kullanarak istediğiniz dizeyi oluşturun .${f#*$t}
and Marry
$s
Sara
Bu eski olduğunu biliyorum ama kimse awk kullanarak bahsetmedi çünkü:
firstString="I love Suzi and Marry"
echo $firstString | awk '{gsub("Suzi","Sara"); print}'
echo [string] | sed "s/[original]/[target]/g"