산출

산출

일부 값이 쉼표로 구분된 다음 입력이 있습니다. 각 값을 분리하고 새 줄에 인쇄하고 싶습니다. 나는 여러 가지 방법을 시도했지만 awk운이 없었습니다. 쉼표로 구분된 값이 세 개 있는 경우 첫 번째 값은 같은 행에 남아 있어야 하고 나머지 값은 새 행에 포함되어야 합니다.

Input File
===========
key1|0|11881|0|0|0|0|11769|0|0|0
key2|2027|345,712|0|1|0|2040|364,729|0|1|0
key3|0|670944|0|0|0|0|495554|0|0|0
key4|1847|1,21|0|0|0|1814|1,22|0|0|0
key5|1880|11,402|0|154|0|1886|11,397|0|151|0
key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
key7|1851|11,757|0|202|0|1856|13,751|0|193|0

Expected Output
================


key1|0|11881|0|0|0|0|11769|0|0|0
key2|2027|345|0|1|0|2040|364|0|1|0
key2|-|712|-|-|-|-|729|-|-|-
key3|0|670944|0|0|0|0|495554|0|0|0
key4|1847|1|0|0|0|1814|1|0|0|0
key4|-|21|-|-|-|-|22|-|-|-
key5|1880|11|0|154|0|1886|11|0|151|0
key5|-|402|-|-|-|-|397|-|-|-
key6|1|65|0|8|0|16684|51|0|8|0
key6|1|4570|-|-|-|0|4176|-|-|-
key6|19137|-|-|-|-|-|-|-|-|-
key7|1851|11|0|202|0|1856|13|0|193|0
key7|-|757|-|-|-|-|751|-|-|-

편집 #1

@Avinash가 남긴 댓글을 바탕으로 시도한 내용은 다음과 같습니다. 나는 이 세계에 처음 왔기 awk때문에 여기에서 수풀을 맴돌고 있을지도 모릅니다. 나는 아래 단계를 따랐다. 당신도 아이디어가 있다면, 더 쉬운 해결책이 있다면 제게 제안해 주세요. 예상되는 해결책을 얻지 못했습니다.

step 1: $ awk -f test.awk a.txt > index.txt --> creates the index files
step 2: $ awk -f test2.awk a.txt > main.txt --> extracts the lines which are comma delimited and duplicate them number of times equal to the comma delimited values
step 3: $ awk -f updt_db1.awk index.txt main.txt --> updates the respective column
index.txt
=========
0|key2|3|345
1|key2|3|712
2|key2|8|364
3|key2|8|729
4|key4|3|1
5|key4|3|21
6|key4|8|1
7|key4|8|22
8|key5|3|11
9|key5|3|402
10|key5|8|11
11|key5|8|397
12|key6|2|1
13|key6|2|1
14|key6|2|19137
15|key6|3|65
16|key6|3|4570
17|key6|7|16684
18|key6|7|0
19|key6|8|51
20|key6|8|4176
21|key7|3|11
22|key7|3|757
23|key7|8|13
24|key7|8|751

main.txt
========
0|key2|2027|345,712|0|1|0|2040|364,729|0|1|0
1|key2|2027|345,712|0|1|0|2040|364,729|0|1|0
2|key2|2027|345,712|0|1|0|2040|364,729|0|1|0
3|key2|2027|345,712|0|1|0|2040|364,729|0|1|0
4|key4|1847|1,21|0|0|0|1814|1,22|0|0|0
5|key4|1847|1,21|0|0|0|1814|1,22|0|0|0
6|key4|1847|1,21|0|0|0|1814|1,22|0|0|0
7|key4|1847|1,21|0|0|0|1814|1,22|0|0|0
8|key5|1880|11,402|0|154|0|1886|11,397|0|151|0
9|key5|1880|11,402|0|154|0|1886|11,397|0|151|0
10|key5|1880|11,402|0|154|0|1886|11,397|0|151|0
11|key5|1880|11,402|0|154|0|1886|11,397|0|151|0
12|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
13|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
14|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
15|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
16|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
17|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
18|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
19|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
20|key6|1,1,19137|65,4570|0|8|0|16684,0|51,4176|0|8|0
21|key7|1851|11,757|0|202|0|1856|13,751|0|193|0
22|key7|1851|11,757|0|202|0|1856|13,751|0|193|0
23|key7|1851|11,757|0|202|0|1856|13,751|0|193|0
24|key7|1851|11,757|0|202|0|1856|13,751|0|193|0

산출

0|key2|2027|345|0|1|0|2040|364,729|0|1|0|
1|key2|2027|712|0|1|0|2040|364,729|0|1|0|
2|key2|2027|345,712|0|1|0|2040|364|0|1|0|
3|key2|2027|345,712|0|1|0|2040|729|0|1|0|
4|key4|1847|1|0|0|0|1814|1,22|0|0|0|
5|key4|1847|21|0|0|0|1814|1,22|0|0|0|
6|key4|1847|1,21|0|0|0|1814|1|0|0|0|
7|key4|1847|1,21|0|0|0|1814|22|0|0|0|
8|key5|1880|11|0|154|0|1886|11,397|0|151|0|
9|key5|1880|402|0|154|0|1886|11,397|0|151|0|
10|key5|1880|11,402|0|154|0|1886|11|0|151|0|
11|key5|1880|11,402|0|154|0|1886|397|0|151|0|
12|key6|1|65,4570|0|8|0|16684,0|51,4176|0|8|0|
13|key6|1|65,4570|0|8|0|16684,0|51,4176|0|8|0|
14|key6|19137|65,4570|0|8|0|16684,0|51,4176|0|8|0|
15|key6|1,1,19137|65|0|8|0|16684,0|51,4176|0|8|0|
16|key6|1,1,19137|4570|0|8|0|16684,0|51,4176|0|8|0|
17|key6|1,1,19137|65,4570|0|8|0|16684|51,4176|0|8|0|
18|key6|1,1,19137|65,4570|0|8|0|0|51,4176|0|8|0|
19|key6|1,1,19137|65,4570|0|8|0|16684,0|51|0|8|0|
20|key6|1,1,19137|65,4570|0|8|0|16684,0|4176|0|8|0|
21|key7|1851|11|0|202|0|1856|13,751|0|193|0|
22|key7|1851|757|0|202|0|1856|13,751|0|193|0|
23|key7|1851|11,757|0|202|0|1856|13|0|193|0|
24|key7|1851|11,757|0|202|0|1856|751|0|193|0|


$ cat test.awk
#!/bin/awk

BEGIN{
FS="|";
counter=0
}

NR == FNR {
for(i=1; i<= NF; i++)
{
  n=split($i,arr,",")
  if ( n > 1)
  for(j=1; j<=n; j++)
       printf "%s|%s|%s|%s\n",counter++,$1,i,arr[j]
}

}



$ cat test2.awk
#!/bin/awk
BEGIN { FS="|"
k=0;
}

NR == FNR {

for(i=1; i<= NF; i++)
{

  n=split($i,arr,",")
  if (n > 1)
     for(j=1; j<=n; j++)
            printf("%s|%s\n",k++,$0)

    }
}


$ cat updt_db1.awk
#!/bin/awk
BEGIN {
    FS = "|"
}
( NR == FNR ) {
    lookup[$1] = $0
}

( NR > FNR ) {
    key = toupper($1)
if (key in lookup){
    split(lookup[key], replacements, "|")
    for (i = 1; i <= NF; i++)
        col[i] = $i;
    for (i=3; replacements[i+1] != "" ; i=i+1){
    j=replacements[i]
    col[j+1] = replacements[i+1]
    }
    for (i = 1; i <= NF; i++)
        printf "%s|", col[i]
    print ""
  }
  else
    print $0;
}

답변1

다음과 같이 사용할 수 있습니다 sed.

    sed 'h;s/,[^|]*//g;x
    /,/{s/|[^,|]*,*/|-/g;H;}
    x;s/-\([^|]\)/\1/g;P;D'

결국 그것은 비교적 간단합니다. 이 작은 스크립트를 데이터에 적용하면 다음과 같은 결과를 얻을 수 있습니다.

key1|0|11881|0|0|0|0|11769|0|0|0
key2|2027|345|0|1|0|2040|364|0|1|0
key2|-|712|-|-|-|-|729|-|-|-
key3|0|670944|0|0|0|0|495554|0|0|0
key4|1847|1|0|0|0|1814|1|0|0|0
key4|-|21|-|-|-|-|22|-|-|-
key5|1880|11|0|154|0|1886|11|0|151|0
key5|-|402|-|-|-|-|397|-|-|-
key6|1|65|0|8|0|16684|51|0|8|0
key6|1|4570|-|-|-|0|4176|-|-|-
key6|19137|-|-|-|-|-|-|-|-|-
key7|1851|11|0|202|0|1856|13|0|193|0
key7|-|757|-|-|-|-|751|-|-|-

기본적으로 sed양쪽 끝에서 각 필드를 처리합니다. 먼저 현재 반복의 복사본을 h이전 공간에 저장합니다. 그런 다음 sed첫 번째 쉼표 뒤의 각 필드에 있는 모든 항목을 삭제합니다. 그런 다음 sed방금 다른 버퍼에 저장한 필드를 삭제할 수 있도록 저장된 복사본으로 다시 전환합니다.

쉼표를 유지하면 삽입된 ewline 문자 뒤의 첫 번째 복사본에 두 번째 복사본을 추가하여 린트할 때 \n적어도 한 번 더 반복한 다음 패턴 공간에서 ewline 문자의 첫 번째 발생만 제거한 다음 제거합니다. 남은 콘텐츠가 시작됩니다.P;D PD\n

답변2

더 유연한 데이터 구조가 필요하다고 생각하기 때문에 awk를 사용하지 않을 것입니다. 나는 Perl을 사용할 것이다:

perl -MList::Util=max -F'\|' -lane '
    $key = shift @F;
    @data = map {[split /,/]} @F;
    do {
        @row = map {shift(@$_) // "-"} @data;
        print join("|", $key, @row);
        $max = max map {scalar @$_} @data;
    } while ($max > 0);
' file
key1|0|11881|0|0|0|0|11769|0|0|0
key2|2027|345|0|1|0|2040|364|0|1|0
key2|-|712|-|-|-|-|729|-|-|-
key3|0|670944|0|0|0|0|495554|0|0|0
key4|1847|1|0|0|0|1814|1|0|0|0
key4|-|21|-|-|-|-|22|-|-|-
key5|1880|11|0|154|0|1886|11|0|151|0
key5|-|402|-|-|-|-|397|-|-|-
key6|1|65|0|8|0|16684|51|0|8|0
key6|1|4570|-|-|-|0|4176|-|-|-
key6|19137|-|-|-|-|-|-|-|-|-
key7|1851|11|0|202|0|1856|13|0|193|0
key7|-|757|-|-|-|-|751|-|-|-

관련 정보