ฉันจะให้ bash / zsh เปลี่ยนข้อความจาก“ foo.foo.foo” เป็น“ foo foo foo foo” ด้วยสคริปต์ / alias ได้อย่างไร?


11

ฉันอาจจะสามารถใช้<หรือหรือ> |บางทีฉันจำเป็นต้องใช้ grep?


2
ข้อความหมายถึงอะไร ไฟล์หรือข้อความบางส่วนในไฟล์? echo "foo.foo.foo" | sed 's/\./ /g'
Zanna

1
@KDG i) คุณต้องสร้างบัญชีแยกต่างหากสำหรับแต่ละไซต์ SE แต่ถ้าคุณใช้ข้อมูลประจำตัวเดียวกันบัญชีจะถูกเชื่อมโยง ii) ในขณะที่ไซต์นี้ถูก จำกัด ไว้ที่อูบุนตูโดยเฉพาะฉันไม่เห็นอะไรที่นี่ซึ่งเป็นหลักฐานพิสูจน์ไม่ได้ว่าคุณไม่ได้ใช้ Ubuntu ดังนั้นฉันจึงไม่มีเหตุผลที่จะปิดมัน
terdon

คำตอบ:


20

คุณสามารถสร้างฟังก์ชั่นและเพิ่มไปยังส่วนท้ายของ~/.bashrcตัวอย่างเช่น

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

ตัวอย่างการใช้งาน:

$ nodot foo.foo.foo
foo foo foo

คุณสามารถใช้ฟังก์ชั่นนี้ใน zsh ได้เช่นกันเพียงแค่เพิ่มลงในของคุณ~/.zshrcแทน


6
@tbodt การเปลี่ยนคำตอบที่ยอมรับเพื่อแทนที่ด้วยคำตอบปัจจุบันอย่างสมบูรณ์ก็ไม่ได้ทำ
muru

28

คุณสามารถใช้คำสั่งtrเพื่อแปลงอักขระ

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

เคล็ดลับเด็ด ๆ ไม่เคยได้ยินคำว่า "tr" มาก่อน
KDG

6
trมีวัตถุประสงค์เพื่อวัตถุประสงค์นี้ sedเป็น overkill
Max Ried

1
+1 อย่างแม่นยำสำหรับtrซึ่งเป็นเครื่องมือที่มีประโยชน์มากซึ่งผู้คนจำนวนมากไม่รู้ว่าด้วยเหตุผลบางอย่าง วิธีที่ง่ายกว่าsedการแปลงคลาสของอักขระทั้งหมด
ปุย

5
อย่าเขียนเป็น 'C' หากคุณทำได้ใน 'awk' ไม่เคยทำใน 'awk' ถ้า 'sed' สามารถจัดการได้ อย่าใช้ 'sed' เมื่อ 'tr' สามารถทำงานได้ อย่าเรียก 'tr' เมื่อ 'cat' เพียงพอ หลีกเลี่ยงการใช้ 'แมว' ทุกครั้งที่ทำได้ - กฏของเทย์เลอร์แห่งการเขียนโปรแกรม
Ross Presser

1
คำตอบที่ดี คำตอบนี้ควรได้รับการยอมรับ
SuB

24

ใช้ทุบตีบริสุทธิ์:

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

9

ใช้Internal Field Separator (IFS)ตัวแปร:

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

สิ่งนี้สามารถใส่ลงในฟังก์ชัน:

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
}

และทำงานดังนี้:

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

3
การรีเซ็ตIFSเป็นเรื่องยุ่งยากมากกว่าการบันทึกลงในตัวแปรและเรียกคืนค่า การ unset IFSและ empty IFSมีพฤติกรรมที่แตกต่างกันดังนั้นคุณต้องตรวจสอบว่ามัน unset หรือเปล่าเพียงแค่ในกรณีที่มันว่างเปล่ามาก่อน
muru

5
ฟังก์ชั่นไม่ทำงานใน subshells เฉพาะตัวแปรบางตัวเท่านั้นที่มีขอบเขตที่แตกต่างกัน (พารามิเตอร์ตำแหน่งและอีกสองสามตัวที่อยู่ในรายการในgnu.org/software/bash/manual/html_node/Shell-Functions.html ) นั่นเป็นเหตุผลที่เรามีlocalคำหลัก
muru

3
ดังนั้นถ้า OP ไม่ได้ตั้งค่าIFSด้วยเหตุผลบางอย่างก่อนหน้านี้ฟังก์ชั่นนี้จะตั้งค่าว่างเปล่าซึ่งมีพฤติกรรมที่แตกต่างกัน
muru

2
@ fedorqui น่าเสียดายที่ไม่สามารถใช้งานได้; เนื่องจากค่า IFS ถูกตั้งค่าช้าเกินไปสำหรับคำสั่งปัจจุบันที่ถูกวิเคราะห์คำ คุณต้องการจริงต้องใช้ (IFS=.; echo ...)subshell ตั้งแต่คำตอบนี้ใช้ฟังก์ชั่น Serg ก็สามารถเปลี่ยนการจัดฟันเพื่อวงเล็บไม่ต้องกังวลเกี่ยวกับการรีเซ็ตไอเอฟเอที่ทุกคน
Muru

2
@fedorqui คุณอาจพบคำถามที่คล้ายกันของฉันใน U & L ที่น่าสนใจ: unix.stackexchange.com/q/264635/70524 (Gilles มักจะให้คำตอบที่ดีมาก)
Muru

4

ทุกคนพลาด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

หนึ่งสามารถใช้xargsยัง นี่คือหนึ่งซับใช้xargs

$ echo "foo.foo.foo" | xargs -d .
foo foo foo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.