Bagaimana saya bisa mendapatkan bash / zsh untuk mengubah beberapa teks dari "foo.foo.foo" menjadi "foo foo foo" dengan skrip / alias?


11

Saya mungkin dapat menggunakan <atau >atau |. Mungkin saya perlu menggunakan grep?


2
Apa yang Anda maksud dengan teks? file atau teks dalam file? echo "foo.foo.foo" | sed 's/\./ /g'
Zanna

1
@KDG i) Anda perlu membuat akun terpisah untuk setiap situs SE, tetapi jika Anda menggunakan kredensial yang sama, akun tersebut akan ditautkan. ii) Meskipun situs ini memang terbatas pada Ubuntu secara eksklusif, saya tidak melihat apa pun di sini yang akan menjadi bukti bahwa Anda tidak menggunakan Ubuntu, jadi saya juga tidak punya alasan untuk menutupnya.
terdon

Jawaban:


20

Anda dapat membuat fungsi dan menambahkan ke akhir Anda ~/.bashrc, misalnya:

nodot() {  echo "$1" | sed 's/\./ /g' ; }

contoh penggunaan:

$ nodot foo.foo.foo
foo foo foo

Anda dapat menggunakan fungsi ini di zsh juga, cukup tambahkan ke Anda ~/.zshrcsebagai gantinya.


6
@tbodt mengubah jawaban yang diterima untuk sepenuhnya menggantinya dengan jawaban saat ini sama sekali tidak dilakukan.
muru

28

Anda dapat menggunakan perintah tr untuk mengonversi karakter.

% echo "foo.foo.foo" | tr '.' ' ' 
foo foo foo

Kiat keren tidak pernah mendengar "tr" sebelumnya
KDG

6
trsebenarnya dimaksudkan untuk tujuan ini. sedberlebihan.
Max Ried

1
+1 tepatnya untuk tr, yang merupakan alat yang sangat berguna yang sepertinya tidak diketahui oleh banyak orang karena alasan tertentu. Jauh lebih sederhana daripada sedmengonversi seluruh kelas karakter.
lembut

5
Jangan pernah menuliskannya dalam 'C' jika Anda bisa melakukannya dalam 'awk'; Jangan pernah melakukannya dalam 'awk' jika 'sed' dapat menanganinya; Jangan pernah menggunakan 'sed' ketika 'tr' dapat melakukan pekerjaan; Jangan pernah memanggil 'tr' saat 'kucing' cukup; Hindari penggunaan 'kucing' bila memungkinkan. - Hukum Pemrogramanaylor
Ross Presser

1
Jawaban bagus. Jawaban ini harus diterima.
SuB

24

Menggunakan bash murni:

bash-3.2$ a='a.a.a'
bash-3.2$ echo "${a/./ }"
a a.a
bash-3.2$ echo "${a//./ }"
a a a

9

Menggunakan Internal Field Separator (IFS)variabel:

bash-4.3$ old_ifs=$IFS
bash-4.3$ IFS="."
bash-4.3$ var="foo.foo.foo"
bash-4.3$ echo $var
foo foo foo
bash-4.3$ IFS=$old_ifs

Ini dapat dimasukkan dengan baik ke dalam fungsi:

split_dot()
{

    string="$1"

    if set | grep -q "IFS";
    then
       ifs_unset="false"
       old_ifs=$IFS
    else
       ifs_unset="true"
    fi

    IFS="."
    echo $string
    if [ "$ifs_unset" == "true" ];
    then
       unset IFS
    else
       IFS=$old_ifs
    fi
}

Dan jalankan seperti itu:

bash-4.3$ split_dot "foo.baz.bar"                                                                             
foo baz bar

3
Menyetel ulang IFSlebih rumit daripada hanya menyimpannya ke variabel dan mengembalikan nilainya. Yang belum disetel IFSdan yang kosong IFSmemiliki perilaku yang berbeda, jadi Anda perlu memeriksa apakah itu tidak disetel atau hanya kosong, kalau-kalau itu kosong sebelumnya.
muru

5
Fungsi tidak berjalan dalam subkulit. Hanya beberapa variabel yang memiliki cakupan yang berbeda (parameter posisi, dan beberapa lainnya dalam daftar di gnu.org/software/bash/manual/html_node/Shell-Functions.html ). Itu sebabnya kami memiliki localkata kunci.
muru

3
Jadi jika OP tidak disetel IFSkarena beberapa alasan sebelumnya, fungsi ini akan mengosongkannya, yang memang memiliki perilaku berbeda.
muru

2
@ fedorqui sayangnya bahkan itu tidak akan berhasil; karena nilai IFS diatur terlambat untuk pernyataan saat ini sedang diuraikan. Anda benar-benar harus menggunakan subkulit (IFS=.; echo ...). Karena jawaban ini menggunakan fungsi, Serg bisa mengubah kurung kurung dan tidak khawatir tentang mengatur ulang IFS sama sekali
muru

2
@fedorqui Anda mungkin menemukan pertanyaan serupa di U&L menarik: unix.stackexchange.com/q/264635/70524 (Gilles selalu memberikan jawaban yang sangat baik)
muru

4

Siapa pun yang terlewatkan awk/ perl/ python/ go:


% awk '{gsub(/[.]/, " ", $0); print}' <<<'foo.foo.foo'                      
foo foo foo

% perl -pe 's/\./ /g' <<<'foo.foo.foo'                                      
foo foo foo

% python -c 'import sys; print sys.stdin.read().replace(".", " ")' <<<'foo.foo.foo'
foo foo foo

% cat input.go
package main

import (
    "os"
    "strings"
    "fmt"
)

func main () {
    args := os.Args
    if len(args) != 2 {
        fmt.Println("Not enough arguments")
        return
    }
    out := strings.Replace(args[1], ".", " ", -1)
    fmt.Println(out)
}

% go run input.go 'foo.foo.foo' 
foo foo foo

1

Satu dapat digunakan xargsjuga. Berikut ini adalah penggunaan satu barisxargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
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.