아래 행의 값을 사용하여 누락된 필드를 채우세요.

아래 행의 값을 사용하여 누락된 필드를 채우세요.

"완전한" 데이터 세트가 있는 몇 개의 행만 있는 세미콜론으로 구분된 데이터 파일이 있습니다. 그들은마지막에데이터세트가 적용되는 행 블록의 위치입니다. 쉘 스크립트(또는 유사한 명령줄 도구)를 사용하여 완전히 채워진 이 행의 데이터를 위 행에 추가하고 싶습니다.

예를 들어 내 파일에 다음 데이터가 포함되어 있다고 가정해 보겠습니다.

86540701
86951202
86262402
86509002
86770802
86459902
86301002
86485102
86556002;Vivo Y11;1630000;NULL;;;
86447404
86161405
86388604
86106105
86426405;Xiaomi Redmi 8A Pro (Redmi 8A Dual);1465000;4;;;

다음과 같이 완전한 행을 찾고 해당 데이터를 위의 불완전한 행으로 바꿀 수 있기를 원합니다.

86540701;Vivo Y11;1630000;NULL;;;
86951202;Vivo Y11;1630000;NULL;;;
86262402;Vivo Y11;1630000;NULL;;;
86509002;Vivo Y11;1630000;NULL;;;
86770802;Vivo Y11;1630000;NULL;;;
86459902;Vivo Y11;1630000;NULL;;;
86301002;Vivo Y11;1630000;NULL;;;
86485102;Vivo Y11;1630000;NULL;;;
86556002;Vivo Y11;1630000;NULL;;;
86447404;Xiaomi Redmi 8A Pro (Redmi 8A Dual);1465000;4;;;
86161405;Xiaomi Redmi 8A Pro (Redmi 8A Dual);1465000;4;;;
86388604;Xiaomi Redmi 8A Pro (Redmi 8A Dual);1465000;4;;;
86106105;Xiaomi Redmi 8A Pro (Redmi 8A Dual);1465000;4;;;
86426405;Xiaomi Redmi 8A Pro (Redmi 8A Dual);1465000;4;;;

답변1

이것은 우리가 사용할 수 있는 작업입니다.tac파일을 역순으로 구문 분석합니다.

tac file | awk -F';' 'NF > 1 {p = substr($0,index($0,FS))} {print $1 p}' | tac

따라서 우리는 어떤 줄도 저장하지 않고 읽은 후 각 줄을 인쇄합니다.

나중에 사용하기 위해 줄의 처음부터 끝까지 NF > 1부분 문자열을 저장할 때 .FS

답변2

awk2채널 접근 방식을 기반으로 한 또 다른 솔루션(GNU awk또는 nawkgensub()기능 필요):

awk -F';' 'FNR==NR{if (NF>1) data[++i]=gensub(/^[^;]+/,"","1");next}
           {if (NF==1) $0=$0 data[j+1]; else j++;} 1' input.csv input.csv

그러면 파일이 두 번 스캔됩니다. 처음에는 여러 필드가 포함된 행의 "데이터 부분" 배열을 만듭니다. 두 번째로, 누락된 데이터 섹션을 대체하고 "완전한" 행을 발견할 때마다 배열 카운터를 증가시켜 다음 데이터 섹션이 다음 행을 대체하도록 합니다.

답변3

사용 sed:

sed -E '
    /;/!{ :a N;/;/!{ s/\n/-/;ta; }; };
    /;/ { s/\n/-/; };
    :c s/([^-]*)-([^;]*)(;.*)$/\1\3\n\2\3/; tc' infile

답변4

GNU sed확장 정규식 모드를 켠 상태에서 사용-E

  • 레코드를 보류 상태로 저장하고 작업이 시작될 때 세미콜론 레코드를 기다립니다.
  • 세미콜론 라인을 만나면 패턴 공간의 마지막 부분(=세미콜론 라인)이 패턴 공간의 첫 번째 부분에 추가되고 첫 번째 부분이 인쇄되고 제거되는 병합 프로세스가 시작됩니다. 이는 패턴 공간이 부족할 때까지 계속됩니다.

$ sed -Ee '/\n/ba
    H;/;/!d;z;x;D;:a
    s/\n(.*\n)?[^;]+(;.*)/\2&/
    P;/\n.*\n/D;s/.*\n//
' file

$ perl -lne '$, = ";";
    push(@A,$_),next if !/;/;
    my $a = s/.*?;//r;
    print $_, $a for splice @A;
    print;
' file

관련 정보