절단으로 절단하지 않으면 어떻게해야합니까?


19

다음 cities과 같은 파일 이 있습니다.

[1598] San Diego, US (inactive)
[4517] St Louis, US (inactive)
[6346] Orlando, US (inactive)

도시 이름을 잘라 내고 싶습니다.

San Diego
St Louis
Orlando

이것은 내가 생각해 낼 수있는 최선입니다.

cut -d ',' -f1 cities | cut -d ']' -f2

그러나 여전히 이름 앞에 공백이 남습니다. cut여러 문자의 구분 기호를 허용하여 사용할 수 있는 유사한 명령이 ]있습니까?


1
tr원하지 않는 문자를 삭제하는 데 유용합니다.
LawrenceC

사람들의 답변에서 코드를 시도하면 세 가지 출력이 표시됩니다. 이것은 귀하의 질문이 100 % 명확하지 않다는 것을 나타냅니다. "잘라 내기"는 제거 또는 선택을 의미합니까? (inactive)상태 를 원하십니까 ? 샘플 출력을 제공하십시오.
Mikel

@Mikel-내가 cut물건을 자르기 위해 사용 하고 있고 내가 가지고있는 실패한 예의 의도를 볼 수 있다는 것을 고려할 때 , 문맥에서 상당히 분명해야합니다. 나는 그것을 더 정리하기 위해 샘플을 제공 할 것입니다. :)
Kit Sunde

아니 정말. 귀하의 질문에 한 문장이 "도시 이름 만 인쇄"로 변경되었습니다. 왜냐하면 "잘라 내기"라는 단어를 사용하는 것이 분명하지 않기 때문입니다. 내 변경이 맞습니까?
Mikel

1
@Kit Sunde : 샘플 출력을 통해 확실히 이해할 수 있습니다. 제목이 귀엽다. "cut out"은 Ctrl + X를 눌렀을 때 어떤 일이 발생했는지를 생각하게하므로 변경을 제안했지만 이것이 귀하의 질문입니다. 다운 투팅은 단순한 의견 불일치 일 때 어리석은 일입니다.
Mikel

답변:


15

Awk ( Awk Info 도 확인 )는 그런 종류의 질문에 아름답습니다. 시험:

awk -F'[],] *' '{print $2}' cities

필드 구분 기호 -F를 정의 [],] *합니다. 닫는 대괄호 나 쉼표 중 하나가 발생하고 그 뒤에 0 또는 임의의 수의 공백이옵니다. 물론 모든 요구 사항에 맞게 변경할 수 있습니다. 정규식을 읽으십시오.

선이 분할되면 분할 결과로 원하는 것을 수행 할 수 있습니다. 여기서는으로 만 두 번째 필드를 인쇄하기로 결정했습니다 print $2. awk 명령어 주위에 작은 따옴표를 사용하는 것이 중요합니다. 그렇지 않으면 $ 2가 쉘로 대체됩니다.


2
]꺾쇠 괄호가 아닙니다. 꺾쇠 괄호는 <>입니다. []"대괄호"또는 "괄호"입니다.
CJM

실제로 정규 표현식을 읽지 않으면 닫는 대괄호를 피해야한다고 생각합니다.
Kit Sunde

@cjm-아마도 독일인 일 수도 있습니다 : news.ycombinator.com/item?id=1181243 :)
Kit Sunde

1
@cjm, 죄송합니다. 대괄호라고 말하면 너무 빨리 입력되었습니다. @ 키트, 저는 독일인이 아닙니다. 내부 닫는 대괄호를 피하고 싶지는 않지만 (목적은 제공되지 않음) 범위의 첫 번째 문자 여야합니다.
asoundmove

12

cut파이프 라인 의 마지막 부분 을 다음과 같이 수정할 수 있습니다 .

cut -d ' ' -f2-

위의 필드 구분 기호는 공백이며 두 번째부터 모든 필드를 선택하려고합니다. 완전한 순서는 다음과 같습니다.

cut -d ',' -f1 cities | cut -d ' ' -f2-

12

보다 복잡한 구문 분석을 위해서는 sed (1) 을 사용해야합니다 .

sed -e 's/\[[0-9]\+\] \([^,]\+\),.*/\1/' cities

또는 pepoluan이-r 제안한대로 정규 표현식을 단순화하는 데 사용하십시오 .

sed -re 's/\[[0-9]+\] ([^,]+),.*/\1/' cities

2
+1. -r을 사용하여 고급 정규식 문자 이스케이프를 방지하여 정규식 패턴을 크게 단순화 할 수 있습니다.
pepoluan

0

나는 일반적으로 sed와 grep을 위해 일이 너무 어려워지면 Perl을 사용합니다.

Perl로 작성하는 방법에는 여러 가지가 있습니다. 예를 들어, 빠른 속도를 선호하거나 입력에서 예상치 못한 약간의 문제를 처리하는 것을 선호 할 수 있습니다 (예 : 하나는 예상 된 두 공간).

한 가지 확실한 방법 (id는 숫자, 도시는 알파벳, 상태는 알파벳이라고 가정) :

while (<>) {
    if (/^\[\d+\] (\w+(?: \w+)*), \w+ \(\w*\)$/) {
        my $city = $1;
        print "$city\n";
    }
}

또는 느리지 만 더 관대합니다 (더 많은 역 추적을 수행함).

while (<>) {
    if (/^.*\]\s+(.*),.*$/) {
        my $city = $1;
        print "$city\n";
    }
}

또는 더 빠름 (폐쇄 브래킷이 처음 나타날 때 필드가 멈춤) :

while (<>) {
    if (/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/) {
        my $city = $1;
        print "$city\n";
    }
}

스크립트가 아닌 명령 행에서 -n기본적으로 while (<>) { BLOCK }루프를 추가하는 옵션을 사용할 수 있습니다 .

perl -ne '/^\[[^]]*\] ([^,]*), \S+ \([^)]*\)$/ and print $1, "\n";' cities

또는 사용법을 잘라내 -F기와 유사하게하려면 awk의 -F옵션 과 유사한 옵션을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

perl -a -n -F'/[],]\s+/' -e 'print $F[1], "\n"' cities

이 방법은 필드에 구분 기호를 포함하지 않는 것으로 가정합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.