많은 양의 데이터가 포함된 데이터 세트가 있습니다.
ID Number: A00001
Name: John Smith
Address: 123 Any Street
City: AnyTown
State: Ohio
Zip: 12345
ID Number: A00002
Name: Jane Doe
Address: 123 Any Street
City: AnyTown
State: Nebraska
Zip: 12346
ID Number: C00003
Name: Jim Shields
Address: 123 Any Street
City: AnyTown
State: Alaska
Zip: 12347
ID Number: D11111
Name: Mary Ellis
Address: 123 Any Street
City: AnyTown
State: Nevada
Zip: 12348
데이터를 추출하여 다음과 같이 분리하고 싶습니다.
ID Number: A00001
Name: John Smith
Zip: 12345
=========================
ID Number: A00002
Name: Jane Doe
Zip: 12346
=========================
ID Number: C00003
Name: Jim Shields
Zip: 12347
=========================
ID Number: D11111
Name: Mary Ellis
Zip: 12348
=========================
나는 찾을 수 있는 모든 grep 및 egrep 옵션을 시도했지만 가장 가까운 방법은 각 출력 줄 사이에 빈 줄(새 줄)을 넣는 것입니다.
답변1
grep
텍스트 형식을 다시 지정하는 도구가 아닌 패턴 일치 도구입니다. 대신 sed
, awk
또는 같은 것을 사용하세요 perl
. 예를 들어:
$ awk '/^(ID Number|Name|Zip):/;
/^[[:blank:]]*$/ { print "=========================" }'
ID Number: A00001
Name: John Smith
Zip: 12345
=========================
ID Number: A00002
Name: Jane Doe
Zip: 12346
=========================
ID Number: C00003
Name: Jim Shields
Zip: 12347
=========================
ID Number: D11111
Name: Mary Ellis
Zip: 12348
이것은 [[:blank:]]*
어떤 줄과도 일치합니다바라보다비어있는 것 같지만 실제로는 스페이스나 탭 같은 가로 공간이 들어있는데... 눈으로만 보기 힘든 부분이기 때문에 생각보다 흔히 발생합니다.
또는 Perl을 사용하십시오.
perl -l -n -e 'print if /^(ID Number|Name|Zip):/;
print "=" x 25 if /^\h*$/' input.txt
또는 먼저 Perl RE의 "수평 공간"을 이해하는 sed
GNU sed 또는 다른 sed가 있는 경우 :\h
sed -n -E -e '/^(ID Number|Name|Zip):/p; s/^\h*$/=========================/p' input.txt
그렇지 않으면 sed를 사용하십시오.
sed -n -E -e '/^(ID Number|Name|Zip):/p; s/^[[:blank:]]*$/=========================/p' input.txt
답변2
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ cat tst.awk
BEGIN {
FS = ":"
split(tgts,tmp)
for (i in tmp) {
tags[tmp[i]]
}
sep = "========================="
}
$1 in tags
!NF { print sep }
END { if (NF) print sep }
$ awk -v tgts='ID Number:Name:Zip' -f tst.awk file
ID Number: A00001
Name: John Smith
Zip: 12345
=========================
ID Number: A00002
Name: Jane Doe
Zip: 12346
=========================
ID Number: C00003
Name: Jim Shields
Zip: 12347
=========================
ID Number: D11111
Name: Mary Ellis
Zip: 12348
=========================
$ awk -v tgts='City:State' -f tst.awk file
City: AnyTown
State: Ohio
=========================
City: AnyTown
State: Nebraska
=========================
City: AnyTown
State: Alaska
=========================
City: AnyTown
State: Nevada
=========================
답변3
각 섹션을 레코드로 처리하고 섹션의 각 행을 필드로 처리하면 출력에서 레코드를 구분하기 위해 등호 줄을 사용하여 각 레코드의 처음 두 필드와 마지막 필드를 출력하려는 것처럼 보입니다.
$ awk -F'\n' -v OFS='\n' -v RS='' -v ORS='\n=========================\n' '{ print $1,$2,$NF }' file
ID Number: A00001
Name: John Smith
Zip: 12345
=========================
ID Number: A00002
Name: Jane Doe
Zip: 12346
=========================
ID Number: C00003
Name: Jim Shields
Zip: 12347
=========================
ID Number: D11111
Name: Mary Ellis
Zip: 12348
=========================
명령줄에서는 먼저 입력 및 출력 필드 구분 기호 값을 개행 문자로 설정합니다. 이렇게 하면 입력과 출력 모두에서 필드가 별도의 줄에 표시됩니다.
그런 다음 레코드 구분 기호를 빈 문자열로 설정하면 "단락 모드"가 활성화됩니다. 즉, 하나 이상의 빈 줄로 구분된 텍스트 섹션을 단일 레코드로 읽을 수 있습니다.
그런 다음 출력 레코드 구분 기호를 등호로 설정하고 양쪽 끝에 줄 바꿈을 추가합니다.
실제 코드는 각 레코드의 첫 번째, 두 번째 및 마지막 필드를 인쇄합니다. $6
대신 사용할 수도 있습니다 $NF
.