스크립트 / 별칭을 사용하여 bash / zsh에서 일부 텍스트를 "foo.foo.foo"에서 "foo foo foo"로 변경하려면 어떻게해야합니까?


11

어쩌면 사용할 수 있습니다 <또는 >|. 아마도 grep을 사용해야합니까?


2
텍스트 란 무엇을 의미합니까? 파일 또는 파일의 일부 텍스트? echo "foo.foo.foo" | sed 's/\./ /g'
잔나

1
@KDG i) 각 SE 사이트에 대해 별도의 계정을 만들어야하지만 동일한 자격 증명을 사용하면 계정이 연결됩니다. ii)이 사이트는 실제로 Ubuntu로만 제한되어 있지만 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과잉입니다.
Max Ried

1
+1 (정확히) tr는 많은 사람들이 어떤 이유로 알지 못하는 매우 유용한 도구입니다. sed전체 문자 클래스를 변환하는 것보다 훨씬 간단 합니다.
솜털 같은

5
'awk'에서 할 수 있다면 절대 'C'로 쓰지 마십시오. 'sed'가 처리 할 수 ​​있으면 'awk'에서 수행하지 마십시오. 'tr'이 작업을 수행 할 수있는 경우 'sed'를 사용하지 마십시오. 'cat'이 충분할 때 'tr'을 호출하지 마십시오. 가능하면 '고양이'를 사용하지 마십시오. -테일러의 프로그래밍 법칙
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은 변수에 저장하고 값을 복원하는 것보다 더 까다 롭습니다. 설정되지 않은 IFS것과 비어있는 IFS것은 다른 동작을하기 때문에, 설정 이 비어 있는지 아니면 비어 있는지를 확인해야합니다.
muru

5
서브 쉘에서 함수가 실행되지 않습니다. 일부 변수 만 범위가 다릅니다 (위치 매개 변수 및 일부는 gnu.org/software/bash/manual/html_node/Shell-Functions.html 에 나열 ). 이것이 바로 local키워드입니다.
muru

3
따라서 OP가 IFS이전에 어떤 이유로 설정되지 않은 경우이 기능은 비어있는 것으로 설정되어 동작이 다릅니다.
muru

2
불행히도 @fedorqui는 작동하지 않습니다. IFS 값이 현재 명령문을 구문 분석하기에 너무 늦게 설정 되었기 때문입니다. 실제로 subshell을 사용해야합니다 (IFS=.; echo ...). 이 답변은 함수를 사용했기 때문에 Serg는 중괄호를 괄호로 바꾸고 IFS 재설정에 대해 전혀 걱정할 수 없었습니다.
muru

2
@fedorqui 당신은 U & L에 대한 비슷한 질문을 찾을 수 있습니다 : unix.stackexchange.com/q/264635/70524 (질은 항상 아주 좋은 답변을 제공합니다)
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.