다음 줄의 값을 인쇄합니다.

다음 줄의 값을 인쇄합니다.

내 파일은 다음과 같습니다

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/'  

관련 정보