다음 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
여러 문자의 구분 기호를 허용하여 사용할 수 있는 유사한 명령이 ]
있습니까?
답변
Awk ( Awk Info 도 확인 )는 그런 종류의 질문에 아름답습니다. 시험:
awk -F'[],] *' '{print $2}' cities
필드 구분 기호 -F
를 정의 [],] *
합니다. 닫는 대괄호 나 쉼표 중 하나가 발생하고 그 뒤에 0 또는 임의의 수의 공백이옵니다. 물론 모든 요구 사항에 맞게 변경할 수 있습니다. 정규식을 읽으십시오.
선이 분할되면 분할 결과로 원하는 것을 수행 할 수 있습니다. 여기서는으로 만 두 번째 필드를 인쇄하기로 결정했습니다 print $2
. awk 명령어 주위에 작은 따옴표를 사용하는 것이 중요합니다. 그렇지 않으면 $ 2가 쉘로 대체됩니다.
답변
cut
파이프 라인 의 마지막 부분 을 다음과 같이 수정할 수 있습니다 .
cut -d ' ' -f2-
위의 필드 구분 기호는 공백이며 두 번째부터 모든 필드를 선택하려고합니다. 완전한 순서는 다음과 같습니다.
cut -d ',' -f1 cities | cut -d ' ' -f2-
답변
보다 복잡한 구문 분석을 위해서는 sed (1) 을 사용해야합니다 .
sed -e 's/\[[0-9]\+\] \([^,]\+\),.*/\1/' cities
또는 pepoluan이-r
제안한대로 정규 표현식을 단순화하는 데 사용하십시오 .
sed -re 's/\[[0-9]+\] ([^,]+),.*/\1/' cities
답변
나는 일반적으로 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
이 방법은 필드에 구분 기호를 포함하지 않는 것으로 가정합니다.