처음 3개 필드가 동일한 중복 행 병합

처음 3개 필드가 동일한 중복 행 병합

다음과 같은 입력이 있습니다(1,000개 행). sed동일한 처음 세 필드와 중복 행을 병합하는 명령을 원합니다.다음에 추가분야만 다르거나삭제"해당 사항 없음":

D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);N/A;SM-1-1
LE040A;1;363;(27.4);N/A;SM-1-2

예상 출력:

D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);(27.4);SM-1-1/SM-1-2

답변1

sed ':n
    s|;N/A;|;|g;$!N
    s|^\(\([^;]*;\)\{3\}\)\(.*\)\n\1|\1\3;|;tn
    P;D
'   <<\IN
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);N/A;SM-1-1
LE040A;1;363;(27.4);N/A;SM-1-2
LE040A;1;363;(28.5);N/A;SM-1-3
LE040A;1;363;(29.6);N/A;SM-1-4
IN

입력의 각 시퀀스에 대해 계속해서 test로 분기하여 각 시퀀스의 꼬리만 병합합니다.

이것은 이식 가능하지만 사용할 수 있다면 작성하기가 더 쉬울 것입니다.-E확장 정규식(BSD나 GNU 버전을 사용하는 것처럼)...

sed -E ':n
        s|;N/A;|;|g;$!N
        s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn
P;D'

한 줄에 모든 내용을 작성하려면 다음을 수행하십시오.

sed -Ee:n -e's|;N/A;|;|g;$!N;s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn' -eP\;D

...효과가 있겠지만 별로 마음에 들지 않았습니다.한 줄그렇게...

어쨌든 첫 번째 출력은 다음과 같습니다.

산출

D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);SM-1-1;(27.4);SM-1-2;(28.5);SM-1-3;(29.6);SM-1-4

다음으로 시작하는 후행 필드를 이동할 수도 있습니다.SM-줄 끝까지 연결하고 각각을 로 구분하면 /다음이 작동해야 한다고 생각합니다.

sed -E ':n
        s|;N/A;|;|g
        s|;(SM-[^;]*)$|/\1|;$!N
        s|^(([^;]*;){3})(.*)\n\1|\1\3;|;tn
P;D'

그런데 필요한 것이 무엇인지 더 명확하고 구체적으로 설명하면 이 작업이 더 쉽고 빨라집니다. 동일한 처음 세 필드만 병합하고 싶지 않은 것 같습니다.어느두 개의 연속 행 및 일치하는 필드 제거N/A~에서어느선을 그은 다음 이동SM-필드 끝어느철사. 대신에, 당신이 말하는 이 모든 개별 직업은 실제로 같은 것을 의미하고 당신이 정말로 다음과 같은 것을 원하는 것 같습니다:

  • 입력 줄에 세 개의 영숫자, 세미콜론으로 구분된 필드, 괄호로 묶인 부동 소수점 필드, 또 다른 콜론 구분 기호가 차례로 포함되어 있는 경우N/A필드에서 다음을 수행해야 합니다.
    1. 다음 행도 이 설명과 일치하는지 확인하고, 그렇다면 현재 행과 다음 행의 처음 세 필드를 비교합니다.
    2. 일치하는 항목이 발견되면 다음 행의 마지막 필드만 유지되고 재귀적으로 다시 시도됩니다.
    3. 그럼에도 불구하고 일치하는 필드는 항상 제거됩니다.N/A, 마지막 것을 ;로 바꿉니다 /.
  • 어쨌든, 표준 출력으로 남은 모든 것을 인쇄하십시오.

차이점이 보이나요? 단일 초기 조건을 기반으로 수행되는 일련의 작업입니다. 이렇게 명확하게 설명할 수 있다면 일치 항목이 처리 시간의 일반성을 보충할 필요가 없습니다.

내가 맞다면 다음이 작동합니다.

sed '   \|;N/A;|!b
        s||/|;$!N
        \|^\(.*(\)\(.*)\)\(.*\)\(\n\1\)\(.*)\)|!P
        s||\4\2;(\5\3|;D
' <<\IN
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);N/A;SM-1-1
LE040A;1;363;(27.4);N/A;SM-1-2
LE040A;1;363;(28.5);N/A;SM-1-3
LE040A;1;363;(29.6);N/A;SM-1-4
IN

D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);(27.4);(28.5);(29.6)/SM-1-1/SM-1-2/SM-1-3/SM-1-4

...여기있어-E라인에...

sed -e'\|;N/A;|!b' -e's||/|;$!N;\|^\(.*(\)\(.*)\)\(.*\)\(\n\1\)\(.*)\)|!P;s||\4\2;(\5\3|;D'

...또는-E확장된 구문...

sed -Ee'\|;N/A;|!b' -e's||/|;$!N;\|^(.*\()(.*\))(.*)(\n\1)(.*\))|!P;s||\4\2(\5\3|;D'

답변2

송신기:

@(repeat)
@  (cases)
@id;@f2;@f3;@val1;@nil;@sm1
@id;@f2;@f3;@val2;@nil;@sm2
@    (do (put-line `@id;@f2;@f3;@val1;@val2;@sm1/@sm2`))
@  (or)
@line
@    (do (put-line line))
@  (end)
@(end)

$ txr data.txr data
D04005;4;279;0;0;SSM-4-1
D04005;5;40;0;0;SSM-5-1
LE040A;1;363;(26.3);(27.4);SM-1-1/SM-1-2

답변3

sed -r ':a;N;s!;N/A!!g;s/^(([^;]*;){3})(.*)\n\1/\1\3;/;T;s!^(([^S][^;]*;){3,})(S*SM-[^;]*);(([^S][^;]*;){1,})(.*)!\1\4\3/\6!;ta' inputfile

출력에서 단 6개 필드의 주석에 대한 암시적 수학은 쌍만 있음을 나타내지만 이는 루프 버전이며 일치 시 출력 SM-1-1/SM-1-2가 변경됩니다.

관련 정보