자르거나 자르지 않을 때 무엇을 사용해야 합니까?

자르거나 자르지 않을 때 무엇을 사용해야 합니까?

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

(또한 확인이상한 정보) 이런 유형의 문제에는 아름답습니다. 노력하다:

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

이는 필드 구분 기호를 -F다음과 같이 정의합니다 [],] *. 이는 닫는 대괄호 또는 쉼표가 한 번 발생하고 그 뒤에 공백이 0개 또는 여러 개가 오는 것을 의미합니다. 물론 어떤 요구 사항에도 맞게 변경할 수 있습니다. 정규식을 읽어보세요.

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

답변2

cut파이프라인의 마지막 항목을 수정하여 다음을 수행할 수 있습니다.

cut -d ' ' -f2-

위의 의미는 필드 구분 기호가 공백이고 두 번째 필드부터 시작하여 모든 필드를 선택한다는 것입니다. 전체 순서는 다음과 같습니다.

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

답변3

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

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

또는 다음을 사용하여 -r정규식을 단순화하려면페폴루안:

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

답변4

sed와 grep이 너무 어려워지면 주로 Perl을 사용합니다.

Perl에서 이것을 작성하는 방법에는 여러 가지가 있습니다. 예를 들어, 속도가 빠르기를 원할 수도 있고 입력에서 예상치 못한 사소한 문제(예: 두 개의 공백이 예상되는 경우)를 처리하기를 원할 수도 있습니다.

명확한 접근 방식(id는 숫자, city는 문자, state는 문자라고 가정):

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

또는 cut과 유사한 사용법을 원하는 경우 -Fawk의 옵션과 유사한 이 옵션을 사용할 수 있습니다 -F. 예를 들면 다음 과 같습니다.

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

이 방법은 어떤 필드에도 구분 기호가 포함되지 않는다고 분명히 가정합니다.

관련 정보