次の行の値を印刷します。

次の行の値を印刷します。

私のファイルは次のとおりです

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の場合、最初の2つのフィールドを印刷します(空でない場合)。

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

関連情報