Bash'de bir karakteri başka bir karakterle değiştir


223

Yapabilmek gerekir bash bir dize bir nokta ( .) ile bir boşluk ( ) değiştirin .

Bunun oldukça basit olacağını düşünüyorum, ama yeniyim, bu yüzden bu kullanım için benzer bir örneği nasıl değiştireceğimizi anlayamıyorum.

Yanıtlar:


390

Satır içi kabuk dizesi değiştirme özelliğini kullanın. Misal:

foo="  "

# replace first blank only
bar=${foo/ /.}

# replace all blanks
bar=${foo// /.}

Daha fazla bilgi için http://tldp.org/LDP/abs/html/string-manipulation.html adresine bakın.


1
Bu çözüm kısa dizelerle uğraşırken iyi olsa da (genel durum sanırım) truzun dizeler için tercih edilebilir . Sistemimde karakterlerden trdaha fazla dizelerle başlayan bash'den daha iyi performans gösterir 1000. Bash'ın zaman karmaşıklığı doğrusaldan daha kötü gibi görünüyor. Küçük bir test: x="$(tr -dc 'a-z \n' </dev/urandom | head -c1M)"; time y="$(tr ' ' \\- <<< "$x")"; time z="${x// /-}". 1M dize uzunluğu ile (= 2 ^ 20) traldı 0.04sve bash 5.0.11 aldı 17s. 2M ile traldı 0.07s(beklenen) ama bash aldı 69s(iki kez dize uzunluğu için sürece 4 kez).
Socowi

@Socowi Bir değişkente saklanan 1Mb ile oynamak gerçekten normal değildir! 10Kb'den fazla bash, çatallanmaktan daha hızlı kalıyor gibi görünüyor tr! ... Kullanılabilir hafıza ve hw kaynaklarına bağlı olarak ... Ama haklısınız !: Yapılacak işin türüne bağlı olarak, özel araçlar daha verimli kalıyor!
F. Hauri

Yeni satırlar gibi çıkış karakterleri için mutlaka arama yapın$'\n'
user2561747

75

Şöyle kullanabilirsiniz tr, şöyle:

tr " " .

Misal:

# echo "hello world" | tr " " .
hello.world

Gönderen man tr:

AÇIKLAMA
     Standart çıkışa yazılarak karakterleri standart girdiden çevirin, sıkıştırın ve / veya silin.


Bu, sorulduğu gibi soru için işe yarasa da, kabul edilen cevaptan daha az geneldir (karakter değiştirme ve ayrıca rastgele dizeler üzerinde çalışır) ve ayrıca harici komut içerir.
Dan Dascalescu

2
Öte yandan, her şeyi belleğe yüklemeden 2GB'lık bir dosya üzerinde çalışır.
aioobe

Soru, keyfi olarak büyük dosyalar değil, "bash dilinde bir dize" ile ilgiliydi.
Dan Dascalescu

52

Bash'da, yapı ile bir dizede desen değiştirme yapabilirsiniz ${VARIABLE//PATTERN/REPLACEMENT}. Sadece /ve //ilk kullanımın yerini almak için değil kullanın . Desen, dosya küreleri gibi bir joker karakter desenidir.

string='foo bar qux'
one="${string/ /.}"     # sets one to 'foo.bar qux'
all="${string// /.}"    # sets all to 'foo.bar.qux'



4

Bunu yollar için deneyin:

echo \"hello world\"|sed 's/ /+/g'|sed 's/+/\/g'|sed 's/\"//g'

Çift tırnaklı dizenin içindeki boşluğu bir +şarkı ile değiştirir, ardından +işareti ters eğik çizgi ile değiştirir , ardından çift tırnak işaretlerini kaldırır / değiştirir.

Bunu Cygwin'deki yollardan birindeki boşlukları değiştirmek için kullanmak zorunda kaldım.

echo \"$(cygpath -u $JAVA_HOME)\"|sed 's/ /+/g'|sed 's/+/\\/g'|sed 's/\"//g'

2
Sorunu çözen iki yıllık bir cevap zaten var sed. Alıntılar önemsizdir.
chepner
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.