내 파일은 다음과 같습니다
User Charts
User ID:
40944827
User Name:
Joe, Neo
Gender:
M
DOB:
3/20/2000 12:00:00 AM - Age: 20 yr. 10 mo. old
다음 형식으로 결과를 사용 awk
하거나 얻고 싶습니다.sed
LastName, First Name,Gender,DOB
Joe,Neo,M,3/20/2000
답변1
실제 입력 파일에 2개 이상의 레코드가 포함되어 있다고 가정합니다. 예를 들면 다음과 같습니다.
$ cat file
User Charts
User ID:
40944827
User Name:
Joe, Neo
Gender:
M
DOB:
3/20/2000 12:00:00 AM - Age: 20 yr. 10 mo. old
User ID:
1234
User Name:
Bob, Slob
Gender:
X
DOB:
5/28/2000 12:00:00 AM - Age: 20 yr. 10 mo. old
코드를 입력 행의 값에 연결하지 않고 CSV로 변환하는 방법은 다음과 같습니다.
$ cat tst.awk
BEGIN { OFS="," }
NR==1 { next }
!(NR%2) { sub(/:.*/,""); hdrs[++numFlds]=$0 }
NR%2 { vals[numFlds]=$0 }
!((NR-1)%8) {
if ( !doneHdr++ ) {
for (fldNr=1; fldNr<=numFlds; fldNr++) {
printf "\"%s\"%s", hdrs[fldNr], (fldNr<numFlds ? OFS : ORS)
}
}
for (fldNr=1; fldNr<=numFlds; fldNr++) {
printf "\"%s\"%s", vals[fldNr], (fldNr<numFlds ? OFS : ORS)
}
numFlds = 0
}
$ awk -f tst.awk file
"User ID","User Name","Gender","DOB"
"40944827","Joe, Neo","M","3/20/2000 12:00:00 AM - Age: 20 yr. 10 mo. old"
"1234","Bob, Slob","X","5/28/2000 12:00:00 AM - Age: 20 yr. 10 mo. old"
for
이것은 정확히 찾고 있는 출력은 아니지만 실제로는 더 유용할 수 있습니다 . 데이터 값을 기반으로 결정을 내리고 선택한 필드의 출력을 변경하는 루프의 조정일 뿐이라는 것을 알 수 있기를 바랍니다. 당신이 원하는대로.
답변2
이것이 귀하가 요청한 것이기 때문에 awk의 솔루션입니다. 이 솔루션은 데이터 파일의 모든 레코드에 대해 작동하며 이름은 다음과 같습니다 datafile
.
$ awk 'BEGIN {print "FirstName,LastName,Gender,DOB"}
/User Name:|Gender:/ {dob=0;rtp=NR+1}
NR==rtp && dob==0 {printf $1 $2 ","}
/DOB:/ {dob=1;rtp=NR+1}
NR==rtp && dob==1 {print $1}' datafile
[output]
FirstName,LastName,Gender,DOB
Joe,Neo,M,3/20/2000
1호선: 인쇄물 제목: "이름, 성, 성별, 생년월일"
2호선: 레코드에 "Username:" 또는 "Gender:"가 포함된 경우 내부 변수 dob 및 rtp는 각각 0 및 NR+1로 설정됩니다.
3호선: 레코드 번호가 rtp이고 dob가 0이면 첫 번째 두 필드를 인쇄합니다(비어 있지 않은 경우).
4호선: 레코드에 "DOB:"이 포함되어 있으면 내부 변수 dob 및 rtp가 각각 1과 NR+1로 설정됩니다.
5호선: 레코드 번호가 rtp이고 dob이 1이면 첫 번째 필드를 인쇄합니다.
답변3
한 번 살펴보고 싶을 수도 있습니다밀러. awk와 마찬가지로 레코드 및 필드 개념이 내장되어 있지만 awk와는 달리 기본적으로 키-값 쌍도 처리합니다.
전임자.
mlr --idkvp --irs '\0' --ifs '\n' --ips ':\n' --ocsvlite put -S '
u = splitnvx(${User Name},", "); $FirstName = u[1]; $LastName = u[2];
d = splitnvx($DOB," "); $DOB = d[1]
' then cut -o -f 'FirstName,LastName,Gender,DOB' file
FirstName,LastName,Gender,DOB
Joe,Neo,M,3/20/2000
답변4
sed의 솔루션은 다음과 같습니다.
sed -e 'N;N;N;N;N;N;N;N;s/.*Name:\n\([^[:space:]]*, [^[:space:]]*\)\nGender:\n\(.\)\nDOB:\n\([^[:space:]]*\).*/LastName, First Name,Gender,DOB\n\n\1,\2,\3/'
출력은 다음과 같아야 한다고 생각합니다. :)-)
sed -e 'N;N;N;N;N;N;N;N;s/.*Name:\n\([^[:space:]]*, [^[:space:]]*\)\nGender:\n\(.\)\nDOB:\n\([^[:space:]]*\).*/LastName, FirstName, Gender, DOB\n\n\1, \2, \3/'