Sample Input:
title role subject
name-JOHN student math
school state NY
county street Phone
name-TOM student math
school state TX
county street Phone
name-LILLY student math
school state LA
county street Phone
name-ROSY student math
school state WA
county street Phone
garbage line 1
garbage line 2
Desired Output
JOHN NY
TOM TX
LILLY LA
ROSY WA
하단 2개의 가비지 라인은 사라져야 합니다. AWk 또는 SED를 사용하고 싶나요?
저는 Sun 운영 체제를 실행하고 있습니다.
답변1
GNU에서 제공sed
sed -n '/^name-/{s///;N;s/[a-z].*\s//p}' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
GNU에서 제공awk
awk -F'[ -]+' '/name/{a=$2}/state/{print a,$3}' OFS='\t' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
통과grep
grep -o '[[:upper:]]\{2,\}' file | paste - -
JOHN NY
TOM TX
LILLY LA
ROSY WA
답변2
여기에 또 다른 이상한 방법이 있습니다. (이제 이것은 @Costas의 추악한 버전이라는 것을 알 수 있습니다):
$ awk -F'[- ]' '($1~/name/){k=$2}($1~/school/){print k,$NF}' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
다음을 사용할 수도 있습니다 grep
.
$ grep -oP '^(name-\K\S+|school.*\s+\K.*)' file | paste - -
JOHN NY
TOM TX
LILLY LA
ROSY WA
물론 특정 예에서는 대문자만 찾을 수 있습니다.
$ grep -Eo '[A-Z]{2,}' file | paste - -
또는 펄:
$ perl -lne '$n=$1 if /^name-(\S+)/; /^school.*\s+(.+)/ && print "$n\t$1"' file
아니면 또 다른 펄:
$ perl -007ne 'print join "\n", (/name-(\S+?)\s.*?state\s+(..)\n/gsm)' file | paste - -
답변3
awk '/name/ {gsub(/name-/,""); printf "%s\t",$1} /school/ {print $3}' file
JOHN NY
TOM TX
LILLY LA
ROSY WA
답변4
명확하게 말하면 "이전 awk
"( /usr/bin/awk/
)을 사용하고 있습니까, 아니면 "새 awk
"( /usr/xpg6/bin/awk
)를 사용하고 있습니까? 온라인맨페이지 참조그리고GNU Awk 도움말 페이지그 차이가 아주 명확하게 드러납니다.
"new"를 의미한다면 awk
변수 할당을 사용하여 이를 수행할 수 있다고 가정하면 -v
다음을 고려할 수도 있습니다.
$ awk -v RS='name-' -v OFS='\t' 'NR>1{print $1,$6}' sample.txt
JOHN NY
TOM TX
LILLY LA
ROSY WA
이름과 상태가 각각 첫 번째( ) 및 여섯 번째( ) 필드 로 해석 -v RS='name-'
되도록 레코드 구분 기호( )를 설정했습니다 . 그런 다음 우리도 설정awk
$1
$6
산출-v OFS='\t'
필수 형식화를 수행하기 위한 필드 구분 기호( )입니다. 조건은 NR>1
첫 번째 줄을 건너뜁니다.
편집하다
awk 'BEGIN{RS="name-";OFS="\t"}NR>1{print $1,$6}' sample.txt
이는 "오래된" 항목에서도 가능합니다 awk
. 테스트해 보세요. awk
"new"라는 원래 제안을 변경하지 않고 유지합니다 .