Ganti satu karakter dengan yang lain di Bash


223

Yang perlu saya lakukan adalah mengganti spasi ( ) dengan titik ( .) dalam sebuah string dalam bash.

Saya pikir ini akan sangat sederhana, tapi saya baru jadi saya tidak tahu cara memodifikasi contoh yang serupa untuk penggunaan ini.

Jawaban:


390

Gunakan penggantian string shell inline. Contoh:

foo="  "

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

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

Lihat http://tldp.org/LDP/abs/html/string-manipulation.html untuk lebih jelasnya.


1
Sementara solusi ini bagus ketika berhadapan dengan string pendek (kasus umum, saya kira) satu mungkin lebih suka truntuk string panjang. Pada sistem saya trmengungguli bash mulai dari string dengan lebih dari 1000karakter. Sepertinya kompleksitas waktu bash lebih buruk daripada linear. Sebuah tes kecil: x="$(tr -dc 'a-z \n' </dev/urandom | head -c1M)"; time y="$(tr ' ' \\- <<< "$x")"; time z="${x// /-}". Dengan panjang string 1M (= 2 ^ 20) trmengambil 0.04sdan bash 5.0.11 mengambil 17s. Dengan 2M trtake 0.07s(diharapkan) tetapi bash butuh 69s(4 kali lebih lama untuk dua kali panjang string).
Socowi

@ Socowi Bermain dengan 1Mb yang disimpan dalam variabel tidak benar-benar biasa! Hingga lebih dari 10Kb, bash tampaknya tetap lebih cepat daripada forking to tr! ... Tergantung pada memori yang tersedia dan sumber daya hw ... Tapi Anda benar !: Tergantung pada jenis pekerjaan yang harus dilakukan, alat khusus tetap lebih efisien!
F. Hauri

Untuk karakter yang lolos seperti baris baru, pastikan untuk mencari$'\n'
user2561747

75

Anda bisa menggunakan tr, seperti ini:

tr " " .

Contoh:

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

Dari man tr:

DESCRIPTION
     Menerjemahkan, memeras, dan / atau menghapus karakter dari input standar, menulis ke output standar.


Meskipun ini berfungsi untuk pertanyaan seperti yang ditanyakan, itu kurang umum daripada jawaban yang diterima (yang bekerja pada penggantian karakter dan juga string arbitrer), dan juga melibatkan dan perintah eksternal.
Dan Dascalescu

2
Di sisi lain itu berfungsi pada file 2gb tanpa memuat semuanya ke dalam memori.
aioobe

Pertanyaannya adalah tentang "string dalam bash", bukan file besar yang sewenang-wenang.
Dan Dascalescu

52

Di bash, Anda bisa melakukan penggantian pola dalam string dengan ${VARIABLE//PATTERN/REPLACEMENT}konstruk. Gunakan adil /dan tidak //untuk menggantikan hanya kejadian pertama. Polanya adalah pola wildcard, seperti gumpalan file.

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



4

Coba ini untuk jalur:

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

Ini menggantikan ruang di dalam string yang dikutip ganda dengan +bernyanyi, lalu menggantikan+ tanda dengan backslash, lalu menghilangkan / mengganti tanda kutip ganda.

Saya harus menggunakan ini untuk mengganti spasi di salah satu jalur saya di Cygwin.

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

2
Sudah ada jawaban dua tahun yang menyelesaikan masalah sed. Kutipan tidak relevan.
chepner
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.