Làm cách nào tôi có thể nhận bash / zsh để thay đổi một số văn bản từ từ foo.foo.foo.Để thành foo foo foo f với một tập lệnh / bí danh?


11

Tôi có thể có thể sử dụng <hay >hay |. Có lẽ tôi cần sử dụng grep?


2
Bạn có ý nghĩa gì bởi một văn bản? một tập tin hoặc một số văn bản trong một tập tin? echo "foo.foo.foo" | sed 's/\./ /g'
Zanna

1
@KDG i) bạn cần tạo một tài khoản riêng cho từng trang SE, nhưng nếu bạn sử dụng cùng thông tin đăng nhập, các tài khoản sẽ được liên kết. ii) Mặc dù trang web này thực sự bị giới hạn chỉ dành riêng cho Ubuntu, tôi không thấy bất cứ điều gì ở đây có thể là bằng chứng không thể chối cãi rằng bạn không sử dụng Ubuntu, vì vậy tôi cũng không có lý do gì để đóng nó.
terdon

Câu trả lời:


20

Bạn có thể tạo một hàm và thêm vào cuối của bạn ~/.bashrc, ví dụ:

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

ví dụ sử dụng:

$ nodot foo.foo.foo
foo foo foo

Bạn cũng có thể sử dụng chức năng này trong zsh, chỉ cần thêm vào ~/.zshrcthay thế.


6
@tbodt thay đổi một câu trả lời được chấp nhận để thay thế hoàn toàn nó bằng một câu trả lời hiện tại đơn giản là không được thực hiện.
muru

28

Bạn có thể sử dụng lệnh tr để chuyển đổi ký tự.

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

những mẹo hay chưa từng nghe về "tr" trước đây
KDG

6
trthực sự có nghĩa là cho chính xác mục đích này. sedlà quá mức cần thiết.
Max Ried

1
+1 chính xác cho tr, đó là một công cụ rất hữu ích mà nhiều người dường như không biết về một số lý do. Cách đơn giản hơn sedđể chuyển đổi toàn bộ các lớp ký tự.
lông mịn

5
Không bao giờ viết nó trong 'C' nếu bạn có thể làm điều đó trong 'awk'; Không bao giờ làm điều đó trong 'awk' nếu 'sed' có thể xử lý nó; Không bao giờ sử dụng 'sed' khi 'tr' có thể thực hiện công việc; Không bao giờ gọi 'tr' khi 'mèo' là đủ; Tránh sử dụng 'mèo' bất cứ khi nào có thể. - Luật lập trình củaTaylor
Ross Presser

1
Câu trả lời tốt đẹp. Câu trả lời này nên được chấp nhận.
SuB

24

Sử dụng bash tinh khiết:

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

9

Sử dụng Internal Field Separator (IFS)biến:

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

Điều này có thể được đặt độc đáo vào một chức năng:

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
}

Và chạy như vậy:

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

3
Đặt lại IFSlà một khó khăn hơn là chỉ lưu nó vào một biến và khôi phục giá trị. Một unset IFSvà một rỗng IFScó hành vi khác nhau, vì vậy bạn cần kiểm tra xem nó không được đặt hay chỉ trống, trong trường hợp nó trống trước.
muru

5
Các chức năng không chạy trong subshells. Chỉ một số biến có phạm vi khác nhau (các tham số vị trí và một số biến khác được liệt kê trong gnu.org/software/bash/manual/html_node/Shell-Fiances.html ). Đó là lý do tại sao chúng ta có localtừ khóa.
muru

3
Vì vậy, nếu OP đã không đặt IFSvì một số lý do trước đây, chức năng này sẽ đặt thành trống, có hành vi khác.
muru

2
@fedorqui thật không may, thậm chí nó sẽ không hoạt động; vì giá trị IFS được đặt quá muộn cho câu lệnh hiện tại được phân tích cú pháp. Bạn thực sự phải sử dụng một subshell (IFS=.; echo ...). Vì câu trả lời này đã sử dụng một hàm, Serg chỉ có thể thay đổi dấu ngoặc thành dấu ngoặc đơn và không lo lắng về việc đặt lại IFS
muru

2
@fedorqui bạn có thể thấy câu hỏi tương tự của tôi trên U & L rất thú vị: unix.stackexchange.com/q/264635/70524 (Gilles luôn đưa ra câu trả lời rất hay)
muru

4

Bất cứ ai bỏ lỡ 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

Ai cũng có thể sử dụng xargs. Đây là một lót sử dụngxargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.